c 不同类型的指针

今天看到了一个问题:c里面,不同类型的指针是否可以互指呢?也就是不同类型的指针之间是否可以互相赋值,我想了想,对于32位机子而言,所有类型的指针都是4Byte(64位就是8Byte,这里只讨论32位),为什么是4Byte呢,原因是32位的机子,内存的地址值就是32位,也就是4Byte,而所有的指针,都是存着内存中某个地址的值的,所以所有类型的指针都是32位。既然如此,理应可以相互赋值啊,于是好奇地敲了两行小代码来尝试一下。首先尝试的代码是这样的:

 1     int *p1 = (int*)malloc(10*sizeof(int));
 2     int i;
 3     for(i = 0; i < 10; ++i){
 4         p1[i] = 1;
 5     }
 6     char *p2 = p1;
 7     printf("p1 = %p, p2 = %p\n", p1,p2);
 8     if(p1==NULL){
 9         printf("NULL\n");
10     } else {
11         for (i = 0; i < 10; ++i)
12         {
13             printf("%d",*(p1+i));
14         }
15         printf("\n");        
16     }

结果编译的时候出现了一个warning,p1和p2都是指向相同的地址没问题,输出结果很正常:

但当我把11行的输出代码换成*(p2+i)的时候,输出结果就不太对了:

这里的输出为什么是1000100010呢?我猜int是4Byte,char是1Byte,所以int*每次移(++)动都会移动4Byte,而char*每次移动(++)则只会移动1Byte,所以这里的1000应该为原来的一个int类型的1,所以我把代码改了一下来验证我的想法:

 1     int *p1 = (int*)malloc(10*sizeof(int));
 2     int i;
 3     for(i = 0; i < 10; ++i){
 4         p1[i] = 1;
 5     }
 6     char *p2 = p1;
 7     printf("p1 = %p, p2 = %p\n", p1,p2);
 8     if(p1==NULL){
 9         printf("NULL\n");
10     } else {
11         for (i = 0; i < 10*4; ++i)  //4个为1组,10个int对于char*来说一共要移动40次
12         {
13             printf("%d",*(p2+i));
14             if((i+1)%4==0){     //每4个换行,方便观察输出而已
15                 printf("\n");
16             }
17         }18     }

我想结果应该是1000 1000 1000这样的,结果果然是这样:

因此,我们可以得知,不同类型的指针,虽然都是存放地址,虽然可以互相赋值,但是由于不同类型的大小不同,所以很容易出错,我们还是严格遵循规范比较好。有一个类型就比较特殊,就是void,void*是可以由任意别的类型进行赋值的,我们这里把p2的类型改成void*来进行尝试,发现直接赋值是不会产生任何的warning和error。但是发现,即便取得到地址,也没有办法进行解引用,也就是无法取的这块内存里面存放的值,原因是无法进行类型检测,根本不知道一个数据多大,一跳要跳多少,所以当我们要用void*指针来进行输出,编译时就会出现如下错误:

posted @ 2017-05-25 16:41  Cccarl  阅读(1468)  评论(0编辑  收藏  举报