• 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
    ", p1,p2);
     8     if(p1==NULL){
     9         printf("NULL
    ");
    10     } else {
    11         for (i = 0; i < 10; ++i)
    12         {
    13             printf("%d",*(p1+i));
    14         }
    15         printf("
    ");        
    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
    ", p1,p2);
     8     if(p1==NULL){
     9         printf("NULL
    ");
    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("
    ");
    16             }
    17         }18     }

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

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

  • 相关阅读:
    Git最佳实践
    Git学习笔记
    Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource
    Python实现按着文件资源管理器里的顺序获取文件列表
    python excel接口自动化测试框架
    java进行屏幕截图
    Java启动桌面应用程序
    java自建一个获取当前电脑桌面的鼠标信息
    vue收集表单数据给后端交互
    vue路由懒加载(延迟加载)的写法..
  • 原文地址:https://www.cnblogs.com/Cccarl/p/6904649.html
Copyright © 2020-2023  润新知