指针类型与互相转换,sizeof(p),sizeof(*p)
指针的类型可以有如下几种:
char *p;//指向内存单元1个字节
short *p;//指向内存单元2个字节
int *p;//指向内存单元4个字节
float *p;//指向内存单元4个字节
double *p;//指向内存单元8个字节
当然,在学习了结构体等构造型别后,指针还可以包含这些新的构造类型。
指针作为变量,存放在内存中,占有内存空间,因此也是有长度的:
sizeof(p)=4 or 8 //计算指针的长度,在x86 4字节, x64
sizeof(*p)//计算指针对应类型的长度
char c = 'a';
char *p1=&c;
int x=10;
int *p2=&x;
char buf[]="hello world";
char *str="hello world";
sizeof(p1)=?
sizeof(p2)=?
sizeof(*p1)=?
sizeof(*p2)=?
sizeof(buf)=?
sizeof(str)=?
sizeof(*buf)=?
sizeof(*str)=?
typedef struct _S
{
int a;
char c;
}S,*PS;
S s;
S *ps= &s;
sizeof(ps)=?
sizeof(*ps)=?
sizeof(p1)=4//指针的长度
sizeof(p2)=4//指针的长度
sizeof(*p1)=1//指针对应类型char的长度
sizeof(*p2)=4//指针对应类型int的长度
sizeof(buf)=12//buf是数组,sizeof计算的是数组的长度,该数组通过"hello world"初始化,包含最后的'\0',共12个字节
sizeof(str)=4//指针的长度
sizeof(*buf)=1//指针对应类型char的长度
sizeof(*str)=1//指针对应类型char的长度
sizeof(ps)=4//指针的长度
sizeof(*ps)=8//指针对应类型S的长度
指针的类型可以互相转换:
下面的代码将字符类型的指针转化为int*类型指针,p所指的内存宽度由1个字节变为了4个字节
char c;
int *p = (int *) &c;
int a;
int *p1 = &a;
char *p2 = (char *)p1;
下面的代码把int*类型指针转化为字符类型指针,内存宽度p2所指的内存宽度由p1的4个字节变为了1个字节。
int a = 0x12345678;
char *p1 = (char *)&a;
int *p2 = &a;
printf("*p1=0x%x,*p2=0x%x\n", *p1,*p2);
通过上面的例子和图,我们可以发现,指针含义可以分为3个方面来理解:
1,它是一个变量,所以也占用一定的内存空间(在X86上占用4个字节,X64上占用8个字节)
2,它的值是一个内存地址。这个地址可以是其它变量的地址。
3,它的地址指向的内存空间具有确定的长度。这是指针与地址的本质区别。如果只告诉你一个内存地址,你不会知道从这个地址开始的内存有多长。但如果告诉你一个指针,你会明确的知道从这个内存地址开始的内存有多长。因为指针都是有类型的。知道了指针的类型,就确定了所指向的内存地址对应的长度。