zoukankan      html  css  js  c++  java
  • 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*指针来进行输出,编译时就会出现如下错误:

  • 相关阅读:
    Codeforces 798C. Mike and gcd problem 模拟构造 数组gcd大于1
    Codeforces 796C. Bank Hacking
    Codeforces 792B. Counting-out Rhyme
    gym 101164 H.Pub crawl 凸包
    hdu 6053 TrickGCD 筛法
    hdu 6041 I Curse Myself 无向图找环+优先队列
    bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
    codeforces gym 101164 K Cutting 字符串hash
    树链剖分求lca
    UESTC 1697 简单GCD问题(一) 筛法
  • 原文地址:https://www.cnblogs.com/Cccarl/p/6904649.html
Copyright © 2011-2022 走看看