我想知道为什么* 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
当我尝试在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
}
答案 0 :(得分:5)
为什么'k'
?
您声明:
char name[] = "john q public";
在访问时,name
被转换为指向第一个元素的指针(指向'j'
的指针)C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
您分配:
int *p = name;
因此p
将存储'j'
的存储位置(地址)作为其值(例如p
指向'j'
)。然后,您打印printf("%c\n", *p+1);
,其中反引号p
(例如*p
)是字符'j'
并由ASCII Table and Description,j + 1 == k
组成,因此您的{ {1}}是完全可以预期的。
jucem n 1 ??
您声明'k'
, 指针类型控制指针算术 。因此,int *p
使p++
前进p
个字节(通常为4个字节),而不是sizeof(int)
个字节(1个字节)。因此,让我们看一下:
sizeof(char)
每增加4个字节,您就有 john q public
-------------
0123456789012
^ ^ ^ ^ 4-bytes per p++
|
p
,其中j uc...
表示您通过访问...
数组末尾的内存来调用未定义行为的位置-所有的赌注都没有。
始终在启用警告的情况下进行编译
始终在启用了警告的情况下进行编译,并且在未经警告的编译之前,不接受的代码。要启用警告,请在您的name
编译字符串中添加-Wall -Wextra -pedantic
(也可以考虑添加gcc/clang
来警告阴影变量)。对于 VS (在Windows上为-Wshadow
),请使用cl.exe
。所有其他编译器将具有类似的选项。阅读并理解每个警告-然后修复它。他们将确定任何问题以及发生问题的确切路线。通过听编译器告诉您的内容,您可以学到很多东西。
如果在启用警告的情况下进行编译,就会发现:
/W3
答案 1 :(得分:3)
一些可能有用的东西:
printf("%c\n", *p+1);
这会将* p的ascii值加1,因此'j'+ 1 ='k'(您得到的值)。
您想要的可能是:
printf("%c\n", *(p+1));
此外,您创建了一个int指针,但我认为在这种情况下您需要一个char指针。
总的来说,这是我建议的用于获取带有指针的字符串的第一个字符的编辑:
char name[] = "john q public";
char *p = name;
printf("%c\n", *(p));
(您不需要“ +1”,因为数组从0开始)