2017-04-15 123 views
-1

在我所知,%c期望int值(如charÇ视为整数),%s预计char *作为参数,但我的疑问是,请问%S需要一个指向字符的块?它可以指向双引号中的单个字符吗?%s和%c格式说明符之间有什么区别?

例如:

char * s = "string"; 
printf("%s",s);// output: string 

如何能够计算出所述存储器块,其中该字符串存在并通过'\0'终止编译器?。

+0

是的,它可以指向长度为1的字符串。 –

+1

*双*引号中的单个字符仍然是一个C字符串,即NUL结尾,与单引号内的单个字符不同。 – Evert

回答

2

编译器如何能够找出 字符串以'\ 0'结尾的内存块?

因为字符串文字(双引号之间的x个字符数量)获取编译器向其添加的NUL终止符\0

char * s = "string"; 
char foo = s[6]; // \0 

所以printf只是打印字符串中的字符,直到找到一个\0

是%s需要指向字符块的指针。它可以指向一个 单引号双引号?

是的你可以,双引号中的单个字符仍然是一个字符串文字,最后是\0

4

在双引号的单个字符仍然是一个C字符串,实际上包含两个字符:单字符加上终止空字符:

char const* str = "a"; // actually points to an array { 'a', '\0' } 

所以你还是有%s使用它。其实,你可以%c使用它,也一样,如果你取消引用字符串:

printf("%c\n", *str); 
//   ^

你可以做到这一点与任何C-字符串(与空单“”的除外),但只有前然后字符将被印...

加成响应您的评论:

函数调用(至少的cdecl和stdcall调用约定)将函数参数压入堆栈完成(在大多数现代系统,类型比int小的int在堆栈中被提升为int)。 printf然后简单地分析格式字符串,如果它发现%s,它会将堆栈中的下一个sizeof(void*)字节解释为指向空终止字符串的指针(因此直接通过str),如果它发现%c,它将直接读取字符从堆栈 - 所以你需要放置一个,而不是一个指针,因此你需要解除引用。

+1

或者,您可以使用'str [0]'而不是'* str'。 –

+0

@Aconcagua为什么%c需要尊重str,但%s不是? –

+0

@ Matec009添加了一些额外的信息给我的答案。 – Aconcagua

0

字符串由字符组成,就像char数组由字符组成一样。

编译器应该聪明,和gcc必须能够识别哪个是哪个函数,[执行相应的操作(如添加一个空结束)

并回答你的问题,是的,它仍然会打印到控制台,就像

char * s = "string"; 
printf("%s",s);// output: string 

将打印到控制台。

相关问题