C 字符串指针。 int 指针与 char 指针
C string pointer. int pointer vs char pointer
我想知道为什么 *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
}
一些可能有帮助的事情:
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 开始)
为什么 '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
,因此您的输出 'k'
完全符合预期。
j ucem n 1??
你声明int *p
,指针类型控制指针运算。因此 p++
将 p
提前 sizeof(int)
字节(通常为 4 字节)而不是 sizeof(char)
字节(1 字节)。那么让我们看看:
john q public
-------------
0123456789012
^ ^ ^ ^ 4-bytes per p++
|
p
增加 4 个字节你有 j uc...
其中 ...
表示你在哪里调用 未定义的行为 通过访问超出 [=15 结束的内存=] array -- 所有赌注都关闭了。
始终在启用警告的情况下进行编译
始终在启用警告的情况下编译,并且不要接受代码,直到它在没有警告的情况下编译.要启用警告,请将 -Wall -Wextra -pedantic
添加到您的 gcc/clang
编译字符串(也可以考虑添加 -Wshadow
以警告阴影变量)。对于 VS(cl.exe
on windows),使用 /W3
。所有其他编译器都有类似的选项。阅读并理解每个警告——然后去修复它。他们将确定任何问题,以及问题发生的确切路线。通过聆听编译器告诉您的内容,您可以学到很多东西。
如果您在启用警告的情况下进行编译,您会发现:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *p = name;
我想知道为什么 *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
}
一些可能有帮助的事情:
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 开始)
为什么 '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
,因此您的输出 'k'
完全符合预期。
j ucem n 1??
你声明int *p
,指针类型控制指针运算。因此 p++
将 p
提前 sizeof(int)
字节(通常为 4 字节)而不是 sizeof(char)
字节(1 字节)。那么让我们看看:
john q public
-------------
0123456789012
^ ^ ^ ^ 4-bytes per p++
|
p
增加 4 个字节你有 j uc...
其中 ...
表示你在哪里调用 未定义的行为 通过访问超出 [=15 结束的内存=] array -- 所有赌注都关闭了。
始终在启用警告的情况下进行编译
始终在启用警告的情况下编译,并且不要接受代码,直到它在没有警告的情况下编译.要启用警告,请将 -Wall -Wextra -pedantic
添加到您的 gcc/clang
编译字符串(也可以考虑添加 -Wshadow
以警告阴影变量)。对于 VS(cl.exe
on windows),使用 /W3
。所有其他编译器都有类似的选项。阅读并理解每个警告——然后去修复它。他们将确定任何问题,以及问题发生的确切路线。通过聆听编译器告诉您的内容,您可以学到很多东西。
如果您在启用警告的情况下进行编译,您会发现:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *p = name;