URL: http://www.cnblogs.com/archimedes/p/point-length-type.html.
Considering the compatibility and portability of applications, pointer length is a problem. On most modern platforms, the length of data pointers is usually the same, regardless of the pointer type, although the C Standard does not specify that all type pointers have the same length, this is usually the case. However, the function pointer length may be different from the Data Pointer length.
The pointer length depends on the machine and compiler used. For example, in modern windows, the pointer length is 32-bit or 64-bit.
Test code:
#include<stdio.h>#include<math.h>#include<stdlib.h>#include<stddef.h>struct p{ int n; float f;};int main(){ struct p *sptr; printf("sizeof *char: %d\n", sizeof(char*)); printf("sizeof *int: %d\n", sizeof(int*)); printf("sizeof *float: %d\n", sizeof(float*)); printf("sizeof *double: %d\n", sizeof(double*)); printf("sizeof *struct: %d\n", sizeof(sptr)); return 0;}
Running result:
Pre-defined types related to pointers:
- Size_t: Used to safely represent the length
- Ptrdiff_t: used to process pointer arithmetic operations
- Intptr_t: used to store pointer addresses
- Uintptr_t: used to store pointer addresses
Size_t type
The size_t type is defined in the Standard C library. It should be an unsigned int and a long unsigned int in a 64-bit system. In C language, this type is located in the header file stddef. h. It is a machine-related unsigned type, and its size is sufficient to ensure the size of objects in the storage memory, it aims to provide a portable method to declare the same length as the system's addressable memory region:
Because the C/C ++ standard only defines a minimum number of digits, rather than a required fixed number of digits. In addition, in the memory, the logarithm of the high alignment storage or low alignment storage systems are different. To improve code portability, it is necessary to define such a data type. Generally, this type defines the memory occupied by it. Of course, some are defined by the compiler or system. The test shows that in a 32-bit system, size_t is 4 bytes, while in a 64-bit system, size_t is 8 bytes. This type can enhance the program portability.
The size_t type is used as the return type of the sizeof operator. It is also a parameter type of many functions, including malloc and strlen.
Size_t is a good practice when declaring length variables such as the number of characters or array indexes. It is often used for cyclic counters, array indexes, and sometimes in Pointer arithmetic operations.
Be careful when printing values of the size_t type. This is an unsigned value. If an incorrect format specifier is selected, unreliable results may be obtained. The recommended format specifier is % zu, in some cases, % u or % lu can be used as an alternative.
Ptrdiff_t type ptrdiff_t is a machine-related data type defined in the C99 standard library. It is defined in the stddef. h file. Ptrdiff_t type variables are usually used to save the results of two pointer subtraction operations. Ptrdiff_t is usually defined as the long int type, size_t is the unsigned type, and ptrdiff_t is the signed integer. The differences between the two types reflect their respective purposes: the size_t type is used to specify the length of the array, which must be a positive number; the ptrdiff_t type should be sufficient to store the gap between two pointers in the same array. It may be a negative number.
#include<stdio.h>#include<stddef.h>#include<string.h>int main(void){ char str[] = "Hello world!"; char *pstart = str; char *pend = str + strlen(str); ptrdiff_t difp = pend - pstart; printf("%d\n", difp); return 0;}
Intptr_t and uintptr_t types
Intptr_t and uintptr_t are used to store pointer addresses. They provide a portable and secure way to declare pointers, and they are the same length as the pointers used in the system, it is useful for converting a pointer into an integer. Uintptr_t is the unsigned version of intptr_t
The intptr_t type is defined as follows:
/* Types for `void *' pointers. */#if __WORDSIZE == 64# ifndef __intptr_t_definedtypedef long int intptr_t;# define __intptr_t_defined# endiftypedef unsigned long int uintptr_t;#else# ifndef __intptr_t_definedtypedef int intptr_t;# define __intptr_t_defined# endiftypedef unsigned int uintptr_t;#endif
From the definition, we can see that intptr_t is different on different platforms and is always the same as the number of addresses, so it is used to store addresses.
In concept, although the address is a pointer, memory management often uses an unsigned integer type to better accomplish this. The kernel treats physical memory as a large array, and the memory address is just an array index. further, a pointer is easy to dereference. When you directly process memory access, you almost never want to dereference it in this way. using an integer type avoids this type of unreference, thus avoiding bugs. therefore, the memory address in the kernel is usually unsigned long, and the fact that the pointer and long integer are always the same size is used, at least on all platforms currently supported by Linux. the C99 standard defines the intptr_t and uintptr_t types to an integer variable that can hold a pointer value.
Test code:
# Include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <stdint. h> # include <string. h> # include <assert. h> # define ID_STR_LEN 12 # define NAME_STR_LEN 10 typedef struct student {char id [ID_STR_LEN]; char name [NAME_STR_LEN]; uint8_t age;} student; student * create_student () {student * stu = (student *) malloc (sizeof (student); if (stu = NULL) return NULL; memset (stu, 0, sizeof (student )); return stu;} void * free_student (student * stu) {if (stu) free (stu); return 0;} static void init_student (student * stu) {assert (stu ); const char * id = "2013112210"; const char * name = "Anker"; uint8_t age = 21; memcpy (stu-> id, id, strlen (id )); memcpy (stu-> name, name, strlen (name); stu-> age = age;} static int handle_student (intptr_t handle) {if (handle = 0) {return-1;} student * stu = (student *) handle; printf ("id: % s \ n", stu-> id); printf ("name: % s \ n ", stu-> name); printf (" age: % u \ n ", stu-> age); return 0;} int main (void) {student * stu; stu = create_student (); init_student (stu); // convert the pointer to intptr_t handle = (intptr_t) stu; handle_student (handle ); free_student (stu); return 0 ;}
References:
Http://www.cnblogs.com/Anker/p/3438480.html