指针表示法

Pau*_*son 6 c arrays pointers

我没有发现指针理论特别麻烦,但我偶尔会被一些符号弄乱.在以下示例中,有人可以解释该行的p = (int*) a工作原理.我对代码的解释表明,这一行只是将第一个数组的第一个元素的地址存储在指针p中,从而printf("%u", *p)产生5.如果是这种情况,这条线只是一种更间接的写作方式p = a[0]吗?

int main()
{
    int a[][4] = {
        5, 7, 5, 9,
        4, 6, 3, 1,
        2, 9, 0, 6
        };



    int *p; // create an integer pointer
    int (*q)[4]; // create a pointer to a four-element integer array

    p = (int*)a; // ?
    q = a;


    printf("%u %u\n", p, q);
    p++;
    q++;
    printf("%u %u\n", p, q);


    return 0;
}
Run Code Online (Sandbox Code Playgroud)

AnT*_*AnT 8

a当在值上下文中使用时,表达式确实将评估为"数组的第一个元素的a地址" - a[0]正确理解它的地址.

但请注意,数组a实际上就是我们所说的2D数组.它是一个数组数组.数组的第一个元素a本身就是一个数组:一个类型的数组int [4].因此,考虑到上述因素,a当在值上下文中使用时,表达式等同于表达式&a[0],表达式是类型的指针,int (*)[4]并且在概念上指向整个 1D数组a[0].

出于这个原因,尝试做

p = a;
Run Code Online (Sandbox Code Playgroud)

将导致编译器发出诊断消息.它是非法的分配int (*)[4]值的int *指针对象.这些类型不兼容.为了抑制此诊断消息,所讨论的代码使用显式强制转换

p = (int *) a;
Run Code Online (Sandbox Code Playgroud)

这有力地将上述int (*)[4]指针值推入p.在典型的实现中,这保留了原始指针的数值,仅执行概念类型转换.

尝试访问值*p通常只会产生值,a[0][0]因为数字上整个a地址的地址a[0]与地址相同并且与地址相同a[0][0].上面的代码利用了这个数字标识,同时使用显式转换来解决类型不兼容问题.


小智 7

我对代码的解释表明,该行只是将第一个数组的第一个元素的地址存储在指针p中

正确.

如果是这种情况,这条线只是一种更间接的写作方式p = a[0]吗?

不,不是."这条线只存储第一个元素的地址 " - 它非常相似

p = &a[0];
Run Code Online (Sandbox Code Playgroud)

但是上面的陈述并不完全正确,因为&a[0]它是类型的int (*)[4].没有演员表的正确作业可能就像

p = &a[0][0];
Run Code Online (Sandbox Code Playgroud)

使用-Wall打开和谷歌偶尔的错误/警告来编译各种声明:)