访问指针数组中的元素

3

我正在尝试使用gcc编译器执行以下C程序。

#include <stdio.h>

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

    printf("\narr0=%d\n", *a);
    printf("arr1=%d\n", *(a+1));
    printf("arr2=%d\n", *a+2);
    printf("arr3=%d\n", *a+3);
    printf("arr4=%d\n", *a+4);

    return 0;
}

Output:-
arr0=1
arr1=2
arr2=9
arr3=13
arr4=17

当我跳过*a+2、*a+3、*a+4的圆括号时,我无法理解发生了什么。对于*a+2,它操作如下:

= *a+2
= *a+(4*2)           4 ->Size of int
= 1+(8)
So, *a+2 = 9

同样的方式也适用于其他情况,但我期望的输出如下:(?)
arr0=1
arr1=2
arr2=3
arr3=4
arr4=5

我知道,我声明指针数组的方式不是最好的。

有人能解释一下这里发生了什么吗?


请注意编译器警告。如果您的编译器没有警告数组初始化程序不是指针,请打开警告或获取更好的编译器(并打开它提供的警告)。 - Jonathan Leffler
2个回答

5
您声明了一堆指向无效地址的指针,因为小整数很常见而且通常不是有效的整数指针。顺便说一下,您应该会得到编译器警告; 在发帖之前阅读并修复它们是个好主意。或者至少提及您是否收到了警告。
一旦您对其中任何一个进行解引用,未定义的行为就会出现。
幸好您从来没有这样做,所有您所做的只是索引数组本身,并使用错误的格式说明符打印指针(您应该使用%p,而不是%d)。

尽管它显示未定义的行为,但输出中存在一些模式,如果我继续打印,这个模式会继续出现。而且这个模式也适用于short int和char类型。 - RajendraW

4

一元运算符 * 的优先级高于二元运算符 +,因此 *(a + i)*a + i 被解释为不同的表达式。

*(a + i) 等价于 a[i];你正在检索数组 a 中的第 i 个元素,所以 *(a + 2) 将与 a[2] 相同,其值为 3

*a + i 等价于 a[0] + i;由于 a[0] 的类型是 int *,所以 a[0] + i 的结果是 a[0] 之后第 iint 指针 的值。如果 sizeof(int *) 是4且 a[0] 等于 1,那么 *a + 1 将是 5*a + 2 将是 9,以此类推。

使用 %p 转换说明符打印指针值:

printf("*a + 2 = %p\n", *a + 2);

如果你想要索引数组,请使用下标符号(a[i])。使用指针符号会令人困惑并容易出错(正如你所发现的那样)。

当我对聊天、short int、double进行操作时,它们显示相同的模式。对于int,它会添加4,对于char - 它会添加4,对于short int* - 它会添加,对于double* - 它会添加7。sizeof(int*),sizeof(char*),sizeof(short int*),sizeof(double*)都是4。如果它正在添加指针的大小,那么对于每种数据类型它应该添加4。但这并没有发生。 - RajendraW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接