我的代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *pi;
short *ps;
pi = malloc(16 * sizeof *pi);
ps = malloc(16 * sizeof *ps);
pi += 8;
ps += 8;
ps = (short*) pi;
*pi = 1000000;
printf("*pi = %d,", *pi);
printf("*ps = %hd\n", *ps);
printf("before incrementing ps : ps = %p\n", ps);
ps++;
printf("after incrementing ps : ps = %p\n", ps);
printf("*ps = %hd\n", *ps);
*ps = 16;
printf("after *ps = %hd -> *pi = %d\n", *ps, *pi);
printf("ps - 1 = %p, -1 + ps = %p\n", ps - 1,-1 + ps);
printf("*(ps - 1) = %hd, *(-1 + ps) = %hd\n", *(ps - 1), *(-1 + ps));
printf("0[ps - 1] = %hd, 1[ps - 2] = %hd, ps[-1] = %hd\n", 0[ps - 1], 1[ps - 2], ps[-1]);
printf("-1[ps] = %hd, -2[ps + 1] = %hd, -3[ps + 2] = %hd\n", -1[ps], -2[ps + 1], -3[ps + 2]);
printf("-3[ps] = %hd, -3[ps + 1] = %hd, -3[ps + 3] = %hd,", -3[ps], -3[ps + 1], -3[ps + 3]);
printf("-3[ps + 4] = %hd\n",-3[ps + 4]);
}
/* format string in printf was adjusted to increase readability */
我的输出:
*pi=1000000,*ps=16960
before incrementing ps:ps=0xbb9030
after incrementing ps:ps=0xbb9032
*ps=15
after *ps=16->*pi=1065536
ps-1=0xbb9030,-1+ps=0xbb9030
*(ps-1)=16960,*(-1+ps)=16960
0[ps-1]=16960,1[ps-2]=16960,ps[-1]=16960
-1[ps]=0,-2[ps+1]=0,-3[ps+2]=0
-3[ps]=0,-3[ps+1]=0,-3[ps+3]=0,-3[ps+4]=0
我读过a[b]
定义为*(a+b)
。因此,ps[-1]==*(ps-1)==*(-1+ps)==-1[ps]
。但是,如输出中所示,虽然除了last之外的所有表达式都具有期望值(16960
),但最后一个表达式的值是0?
为什么会这样? -x [ps]是否会产生未定义的行为,导致编译器只使用0?
为了您的信息,我使用gcc。 gcc -v
输出gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)
。
答案 0 :(得分:4)
一元否定-
的优先级低于[]
。
因此-1[ps]
评估为-(1[ps])
。
您还应该注意,指针算法仅在数组中定义:允许您设置(但不是取消引用)指针一个超过数组末尾的指针,或者一个超过标量地址的指针。
其他一切都非常明显:特别是你不能在数组边界之外访问。