【发布时间】:2017-10-12 15:07:20
【问题描述】:
我的代码:
#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]。但是,从输出中可以看出,虽然除了最后一个表达式之外的所有表达式都具有预期值(16960),但最后一个表达式的值是 0?
为什么会这样? -x[ps] 是否会产生未定义的行为,导致编译器只使用 0?
为了您的信息,我使用 gcc。 gcc -v 输出gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)。
【问题讨论】:
-
您知道编译器忽略空格,不是吗?这段代码太难读,太无聊了,请解释你的确切问题并尝试在更简单的程序中重现它。另外,你知道
1[x] is the same as x[1]吗? -
我不知道你在说什么或者这段代码应该实现什么。
-
@EugeneSh。这是一段用于试验指针算法的代码。
-
这个实验在我看来更多关于可以用来执行指针算术的语法,这是一个有趣的话题,但你应该尽量坚持给定的语法,比如
x[n]可读且直观。 -
然后分离出让你困惑的代码段,并解释预期的和实际的行为。