为什么C的printf格式string同时具有%c和%s?

为什么C的printf格式string同时具有%c%s

我知道%c代表一个单独的字符, %s代表一个以空字符结尾的string,但是string表示本身是不够的?

可能要区分以空字符结尾的字符和字符。 如果他们只有%s ,那么每个单独的字符也必须以null结尾。

 char c = 'a'; 

在上面的情况下, c必须是空终止的。 这是我的假设,虽然:)

%s打印字符,直到达到0 (或'\0' ,同样的事情)。

如果你只是有一个char x; ,用printf("%s", &x);打印printf("%s", &x);你必须提供地址,因为%s期望char* – 会产生意想不到的结果,因为&x + 1可能不是0

所以你不能只打印一个单一的字符,除非它是空终止(非常无效)。

编辑:正如其他人已经指出的,两个期望VAR参数不同的事情 – 一个指针,另一个单一的字符。 但是那个区别有些清楚。

其他人提到的问题是,单个字符必须是空的而不是真实的。 这可以通过提供一个精确的格式%.1s来处理。

我认为更重要的是,对于任何forms的%s ,你都必须提供一个指向一个或几个字符的指针。 这意味着你将无法打印右值(计算expression式,函数返回等)或寄存器variables。

编辑:我真的很生气的反应这个答案,所以我可能会删除这个,这是真的不值得。 似乎人们甚至没有读过这个问题,也没有知道如何去欣赏这个问题的技术性。

说清楚:我不是说你应该比%c更喜欢%.1s 我只是说,为什么%c不能被replace的原因是不同于其他答案假装告诉。 这些其他的答案在技术上是错误的。 空终止不是%s的问题。

printf函数是一个可变参数函数,这意味着它具有可变数量的参数。 在调用函数(printf)之前,将参数压入堆栈。 为了使printf函数能够使用这个堆栈,它需要知道关于堆栈内容的信息,格式化string被用于这个目的。

例如

 printf( "%c", ch ); tells the function the argument 'ch' is to be interpreted as a character and sizeof(char) 

 printf( "%s", s ); tells the function the argument 's' is a pointer to a null terminated string sizeof(char*) 

printf函数内部不可能确定堆栈内容,例如区分'ch'和's',因为在C中在运行时没有types检查。

%s说打印所有的字符,直到你find一个null(把这个variables作为一个指针)。

%c表示只打印一个字符(把variables当作字符码)

使用%s作为字符是行不通的,因为字符将被当作一个指针来对待,然后它将尝试打印所有位于内存中的字符,直到find一个null

从其他方面窃取答案以不同的方式解释。

如果你想使用%s来打印一个字符,你可以使用下面的命令来正确的传递一个字符的地址,并且不要在屏幕上写垃圾,直到find一个null。

 char c = 'c'; printf('%.1s', &c); 

对于%s ,我们需要提供string的地址,而不是它的值。

对于%c ,我们提供了字符的值。

如果我们使用%s而不是%c ,那么我们如何在字符后面提供'\0'

我喜欢给这个有趣的问题增加另一个观点。

真的,这涉及到数据input。 我已经在这里看到了答案,说明你可以提供一个指向char的指针,并提供一个

 "%.1s" 

这确实是事实。 但答案在于Cdevise人员试图为程序员提供灵活性,实际上是减less应用程序占用空间(尽pipe很小)的方法。

有时程序员可能会喜欢运行一系列if-else语句或switch-case语句,其中需要根据状态输出一个字符。 为此,对字符进行硬编码确实可以减less内存中的实际空间,因为单字符是8位而32位或64位(对于64位计算机)的指针。 指针将占用更多的内存空间。

如果你想通过使用实际的字符和指向字符的指针来减小大小,那么在printftypes的操作符中有两种方法可以这样做。 其中一个就是closures.1s,但是程序应该如何确定地知道你真的提供了一个chartypes的指针,而不是指向一个string(char数组)的指针呢? 这就是为什么他们跟“%c”一样,因为它是不同的。

有趣的问题:-)

C具有%c%s格式说明符,因为它们处理不同的types。

一个char和一个string和晚上和1差不多。

%c需要一个char,它是一个整型 ,并根据编码规则打印它。

%s需要一个指向包含char值的内存位置的指针 ,并根据编码规则在该位置打印字符,直到find0(空)字符。

所以你们看到,在这两种情况下,这两种情况看起来是一样的,他们没有太多共同之处,因为一个人用价值观来工作,另一个用指针。 一种是将特定的整数值解释为ascii字符的指令,另一种是通过char迭代char的内存位置的内容,并解释它们,直到遇到一个零值。

由于没有人提供任何参考答案,所以这里是pubs.opengroup.com的printf规范,它与IBM的格式定义类似

%C

int参数应该被转换为一个无符号的字符,并且结果字节将被写入。

%S

参数应该是一个char数组的指针。 来自数组的字节应写入(但不包括)任何终止空字节。 如果指定了精度,则不应超过这么多字节。 如果未指定精度或大于数组的大小,则应用程序应确保数组包含空字节。

我用printf("%.1s", &c)printf("%c", c)做了一个实验。 我用下面的代码来testing,而bash的time效用得到了运行时间。

  #include<stdio.h> int main(){ char c = 'a'; int i; for(i = 0; i < 40000000; i++){ //printf("%.1s", &c); get a result of 4.3s //printf("%c", c); get a result of 0.67s } return 0; } 

结果表明使用%c%.1s快10倍。 所以,尽pipe%s可以完成%c的工作,但仍然需要%c来提高性能。