C指针问题,二级指针是否与这个形式相等?

#include <stdio.h>
int main(void)
{
    int a;
    int *ptr_a,*ptr_ptr_a;
    int **ptr;
    a=0;
    ptr_a = &a;
    ptr_ptr_a = (int*)&ptr_a;
    ptr = &ptr_a;
    //    给A赋值有两种方式:
    **ptr = 1;
    //    或
    *(int*)*ptr_ptr_a = 1;
    printf("%d",a);
    return 0;
}

如上程序,其中

**ptr

*(int*)*ptr_ptr_a

的作用是相等的吗?
想请问一下这样子有什么弊端?(除开语法上写着麻烦,会不会造成bug?)

阅读 3.1k
3 个回答

不相等。
从内部储存的角度考虑的话,我觉得是会出bug的。
首先,对于c程序中,内存地址的长度都是一致的,所以用int*int**储存地址是不会出现数据溢出的问题,都是用一个long的大小储存地址的。(其中32位系统大小为4byte,64位系统为8byte)
其次,对于一个指针所指向的内存程序将会根据指针的类型决定从地址起始处开始读几个byte,如果是一个int*的指针那么将会读入一个int的大小即4byte,如果是一个int**那么将会读入一个long的大小(4byte或者8byte),所以如果题主想要用ptr_ptr_a来修改a值的话我们来看一下,第一步解引用*ptr_ptr_a的话,由于ptr_ptr_a是一个int*的指针所以程序从ptr_ptr_a处读入一个int的大小,好了,到这为止对于64位的系统的朋友们就可能会出bug了,因为他们的地址长度是8个byte,有4个byte被截断了,32位的系统应该没事,因为他们的地址大小就是4个byte,所以对于第一步解引用就会可能会出现bug。如果题主还是要折腾的话那应该这样写:

*(int*)*(int**)ptr_ptr_a=1;  

其实这样的话也就和`int**`没差啦?
以及那个**ptr题主写的是没问题的~

有区别的。
你定义的 int **ptr 是指针的指针,它是指向指针的。我们知道,指针也是一个变量,它也需要内存空间存储,那么必然的指针变量也是拥有一个地址的。那么 ptr = &ptr_aptr 存储的就是 ptr_a 地址了。所以这时,你想用 ptr 来解引用获取 a 的值,光是 *ptr 是不够的,因为 *ptr == ptr_a 的,是后者的地址,所以你必须要再解引用一次。

ptr_ptr_a = (int*)&ptr_a;,由于 ptr_ptr_a 是一个 int * 类型的指针变量,而 &ptr_aint **,所以你需要强制转换成 int *,编译器才会认为它是合法的指针变量。而后面 *ptr_ptr_a 是一个 int 类型,可是前面你实际上存储的是 a 的指针,所以你必须要再解引用一次才可以。可是,一个 int 类型的变量并不能解引用,所以你需要强制转换成类型 int* 方能解引用。

最后,第二种写法。本来操作内存就很复杂了,你还要一会存指针一会存值,那么你出 bug 的概率就会多得多。

个人愚见,希望能帮助你。

直接*ptr就行,不需要那样强转,如果强转注意加括号,如(int )(ptr),或许不加括号也可以,在有时候不确定的时候加括号

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进