printf(“c”和*(*(ptr+;i)和printf(“s”和*(*(ptr+;i)和#x2B;x))之间的差异
我有一个指针数组,当我尝试这个C代码时,得到了一个分段错误。我做错了什么printf(“c”和*(*(ptr+;i)和printf(“s”和*(*(ptr+;i)和#x2B;x))之间的差异,c,pointers,printf,undefined-behavior,c-strings,C,Pointers,Printf,Undefined Behavior,C Strings,我有一个指针数组,当我尝试这个C代码时,得到了一个分段错误。我做错了什么 char *ptr[] = {"exam","example","testexample"}; printf("%c\n",*(*(ptr+2)+7)); printf("%s\n",*(*(ptr+2)+7)); 在给出预期结果的第一条打印语句的输出中 printf("%c\n",*(*(ptr+2)+7)); 但是第二个不是给出 mple 正在给予 printf("%s\n"
char *ptr[] = {"exam","example","testexample"};
printf("%c\n",*(*(ptr+2)+7));
printf("%s\n",*(*(ptr+2)+7));
在给出预期结果的第一条打印语句的输出中
printf("%c\n",*(*(ptr+2)+7));
但是第二个不是给出
mple
正在给予
printf("%s\n",*(*(ptr+2)+7)); Segmentation fault (core dumped)
我做错了什么?表达式的类型
char *ptr[] = {"exam","example","testexample"};
printf("%c\n",*(*(ptr+2)+7));
printf("%s\n",*(*(ptr+2)+7));
*(*(ptr+2)+7)
是char
。因此,printf
的第一个调用是正确的
但是第二个调用不正确,因为格式说明符%s
需要类型为char*
的参数。因此,通过表达式*(*(ptr+2)+7)
获得的字符值,即字符'm'
(例如,在ASCII中具有值100
)被解释为地址
在第二次通话中,只需使用
*(ptr+2)+7
这是一个演示程序
#include <stdio.h>
int main(void)
{
char *ptr[] = { "exam", "example", "testexample" };
printf( "%c\n", *( *( ptr + 2 ) + 7 ) );
printf( "%s\n", *( ptr + 2 ) + 7 );
return 0;
}
表达式的类型
*(*(ptr+2)+7)
是char
。因此,printf
的第一个调用是正确的
但是第二个调用不正确,因为格式说明符%s
需要类型为char*
的参数。因此,通过表达式*(*(ptr+2)+7)
获得的字符值,即字符'm'
(例如,在ASCII中具有值100
)被解释为地址
在第二次通话中,只需使用
*(ptr+2)+7
这是一个演示程序
#include <stdio.h>
int main(void)
{
char *ptr[] = { "exam", "example", "testexample" };
printf( "%c\n", *( *( ptr + 2 ) + 7 ) );
printf( "%s\n", *( ptr + 2 ) + 7 );
return 0;
}
您的参数*(*(ptr+2)+7)
计算结果为一个字符,其值'm'
,该值(在基于ASCII的平台上)与数字109相同
当你这样做的时候
printf("%s\n",*(*(ptr+2)+7));
这与
它被编译成机器代码,将数字109加载到寄存器中,并将该寄存器推送到堆栈上。它没有告诉printf它在哪里找到的任何东西--
'm`--只有一个原始ASCII值被传递给函数
printf
然后尝试将109解释为指向某些字符的指针,而不是字符本身,因为这是您通过编写%s
要求它执行的操作。不出所料,这会出现可怕的错误,因为109不是程序可以访问的任何内容的地址
如果要打印字符串的结尾,可以改为编写
printf("%s\n", *(ptr+2)+7 );
不将*
运算符应用于要传递的指针。您的参数*(*(ptr+2)+7)
计算为一个值为'm'
的字符,该值(在基于ASCII的平台上)与数字109相同
当你这样做的时候
printf("%s\n",*(*(ptr+2)+7));
这与
它被编译成机器代码,将数字109加载到寄存器中,并将该寄存器推送到堆栈上。它没有告诉printf它在哪里找到的任何东西--
'm`--只有一个原始ASCII值被传递给函数
printf
然后尝试将109解释为指向某些字符的指针,而不是字符本身,因为这是您通过编写%s
要求它执行的操作。不出所料,这会出现可怕的错误,因为109不是程序可以访问的任何内容的地址
如果要打印字符串的结尾,可以改为编写
printf("%s\n", *(ptr+2)+7 );
不将*
运算符应用于要传递的指针。((ptr+2)+7)是字符值
因此,第一条语句是正确的,因为“%c”告诉printf第一个参数是char:
printf("%c\n",*(*(ptr+2)+7));
但在第二条语句中,“%s”告诉printf第一个参数是(char*),即指向char的指针。
这样,当程序执行时
printf("%s\n",*(*(ptr+2)+7));
查看((ptr+2)+7)的值(一个char值,在本例中为'm'),就好像它是一个char指针。
这就是分割错误的原因
因此,更正后的secon声明将是
printf("%s\n",*(ptr+2)+7);
希望这有帮助。((ptr+2)+7)是一个字符值
因此,第一条语句是正确的,因为“%c”告诉printf第一个参数是char:
printf("%c\n",*(*(ptr+2)+7));
但在第二条语句中,“%s”告诉printf第一个参数是(char*),即指向char的指针。
这样,当程序执行时
printf("%s\n",*(*(ptr+2)+7));
查看((ptr+2)+7)的值(一个char值,在本例中为'm'),就好像它是一个char指针。
这就是分割错误的原因
因此,更正后的secon声明将是
printf("%s\n",*(ptr+2)+7);
希望这能有所帮助。问题在于表达式
*(*(ptr+2)+7)的使用。
很难看出它的作用。这种结构主要用于还不熟悉C语言的初学者。这就是为什么C有一个语法糖:*(*(ptr+2)+7)
完全等同于ptr[2][7]
,这是您应该使用的形式
现在,ptr[2][7]
显然是一个char
,但是%s
需要一个指向char
的指针,它是以null结尾的字符串中的第一个字符,所以让我们传入一个指向该字符的指针:
问题在于表达式
*(*(ptr+2)+7)
的使用-很难看出它的作用。这种结构主要用于还不熟悉C语言的初学者。这就是为什么C有一个语法糖:*(*(ptr+2)+7)
完全等同于ptr[2][7]
,这是您应该使用的形式
现在,ptr[2][7]
显然是一个char
,但是%s
需要一个指向char
的指针,它是以null结尾的字符串中的第一个字符,所以让我们传入一个指向该字符的指针:
在第二个示例中,您将字符值
'm'
用作无效指针值的指针。删除一个*
作为printf(“%s\n”,*(ptr+2)+7)代码>一件更容易理解的事情是记住,对于任何指针ptr
和索引i
,表达式*(ptr+i)
完全等于