ehp*_*k86 0 c pointers c-strings
我想知道为什么 * p+1输出 k 而不是 "o"?我试过用调试器运行它,但似乎仍然无法解决这个问题。
char name[] = "john q public";
int *p = name;
printf("%c\n", *p+1); // output expected -> o, but got k
printf("%c", name[0]); // output as expected -> j
Run Code Online (Sandbox Code Playgroud)
当我尝试在 for 循环中输出名称时,我得到了奇怪的值。
int len = strlen(name);
for(int i=0; i<len; i++ ){
printf("%c", *p++); //expected -> john q public, but got -> j ucem n 1
}
Run Code Online (Sandbox Code Playgroud)
为什么'k'?
你声明:
char name[] = "john q public";
Run Code Online (Sandbox Code Playgroud)
访问时,name转换为指向第一个元素的指针(指向 的指针'j')C11 标准 - 6.3.2.1 其他操作数 - 左值、数组和函数指示符 (p3)
您分配:
int *p = name;
Run Code Online (Sandbox Code Playgroud)
因此p,'j'将存储(例如p指向'j')的内存位置(地址)作为其值。然后你打印printf("%c\n", *p+1);derefereing p(eg *p) 是字符'j'和ASCII Table 和 Description , j + 1 == k,所以你的输出'k'是完全预期的。
j ucem n 1??
您声明int *p,指针类型控制指针算术。因此按字节(通常为 4 字节)而不是字节(1 字节)p++前进。那么让我们看看:psizeof(int)sizeof(char)
john q public
-------------
0123456789012
^ ^ ^ ^ 4-bytes per p++
|
p
Run Code Online (Sandbox Code Playgroud)
增加 4 个字节,您拥有j uc...where...指示您通过访问数组末尾以外的内存来调用未定义行为的位置name- 所有赌注都已关闭。
始终在启用警告的情况下编译
始终在启用警告的情况下进行编译,并且在没有警告的情况下编译之前不要接受代码。要启用警告添加-Wall -Wextra -pedantic到您的gcc/clang编译字符串(也考虑添加-Wshadow到阴影变量的警告)。对于VS(cl.exe在 Windows 上),使用/W3. 所有其他编译器都有类似的选项。阅读并理解每个警告——然后去修复它。他们将识别任何问题,以及它们发生的确切线路。通过聆听编译器告诉您的内容,您可以学到很多东西。
如果您在启用警告的情况下进行编译,您会发现:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *p = name;
Run Code Online (Sandbox Code Playgroud)