嗨,我很困惑,得到下面的解释,有人可以解释给我吗?提前致谢.
#include<stdio.h>
int main(){
char *arr,c;
arr = &c;
arr++;
*arr = 'a';
arr++;
*arr = 'b';
arr++;
*arr = 'c';
arr--;
arr--;
printf("\narr 1 = %c",arr);
printf("\narr 2 = %c",arr[1]);
printf("\narr 3 = %c",arr[2]);
getch();
return 1;
}
Run Code Online (Sandbox Code Playgroud)
输出为:
arr 1 = a
arr 2 = b
arr 3 = c
但如果改变线:
printf("\narr 1 = %c",arr);
Run Code Online (Sandbox Code Playgroud)
同
printf("\narr 1 = %c",arr[0]);
Run Code Online (Sandbox Code Playgroud)
现在输出为:
arr 1 =
arr 2 = b
arr 3 = c
为什么'a'没有印刷.?
*对于所有那些质疑程序编码不好的人来说..我知道使用像这样的指针不是一个好的编码实践,但我的问题是为什么arr [0]不打印任何地方,如arr [1]&arr [ 2]是打印分配的内容?
在该程序的第一个版本中,可能发生的是:
c堆栈的某个地址,比如1003(单个字节).arr在堆栈上放置一些地址,比如说1004-1007(四个字节).arr = &c;将地址c1003放入arr.arr++;添加了一个arr,所以它现在是1004而不是1003.*arr = 'a';写到'a'了arr积分的地方.现在这是C标准未定义的行为.当arr设置&c为时,该位置的对象中只有一个字节,并且C标准不保证在对象外部递增该地址后写入其他位置时会发生什么.arr,所以你写入'a'其中一个字节arr.这可怕地改变了地址arr.arr++;再次递增地址,然后*arr = 'b';写入'b'某处.我们不知道在哪里,因为arr它的价值很低.arr++;再次递增地址,然后*arr = 'c';写入'c'某处.我们不知道在哪里.arr--;和arr--;地址返回到它后的值'a'写入.printf调用传递值,arr以使用"%c"说明符打印."%c"用于打印字符,但是arr您传递它是一个指针.但是,您之前'a'写入了指针,因此指针的值'a'在其中一个字节中.printf打印指针值中的一个字节,在本例中是您编写的相同字节'a'.所以打印出"a".你不能在其他C实现中依赖这种情况.这是发生在仅仅是因为编译器碰巧把这个情况arr在内存刚过c在内存中,这样的声明*arr = 'a';中写道'a'成arr.这不会发生在所有C实现中.你真是幸运."'a'进入arr,arr被指向的地方,虽然我们不知道在哪里.我们叫这个位置x.arr++;并*arr = 'b';写到'b'该位置x+1.arr++;并*arr = 'c';写到'c'该位置x+2.arr--;语句返回arr指向x.所以arr[1]是字符的x+1,这是'b'和arr[2]是'c'.将这些传递给要用"%c"打印的printf打印"b"和"c".在该程序的第二个版本中,何时arr[0]传递给printf:
arr是通过写入'a'其中一个字节而形成的值.这是一些"随机"地址,指向我们没有控制的位置.显然,那里有一个0字符,或者其他一些非打印字符,所以,当arr[0]传递给它时printf,什么都没有打印出来.arr[1]和arr[2]打印"B"和"C",因为代码写的'b',并'c'到这些位置.小智 6
arrarr[0]因为arr[0] 取消引用数组,所以不等价.正确的等价物将是&arr[0].
顺便说一下,你正在做什么调用未定义的行为,因为在递增之后arr,它指向一个无效的内存位置 - 最初它指向一个字符,所以你不能假设它后面有任何东西.
这只是未定义的行为 - arr++; *arr = 'a';因为arr指向单一行为是非法的char.任何事情都可能发生.
| 归档时间: |
|
| 查看次数: |
983 次 |
| 最近记录: |