空字节的格式说明符%s%d和%c的计算机级别差异

空字节的格式说明符%s%d和%c的计算机级别差异,c,C,问题是在最后三个语句1、2和3中到底发生了什么。在机器级别内部发生的事情。打印时%s将其视为null、%d将其视为0、%c将其视为无 有人能从机器层面的深度来解释这些吗?首先:这与机器层面无关。这里的一切都发生在运行时,或者更具体地说,发生在printf的实现中。此外,使用错误的格式说明符进行的所有转换都可能会带来麻烦,因为如果您没有将参数强制转换为格式说明符的正确类型,则无法保证这些转换实际上是正确传递/读取/解释的(例如,由于长度不同) 首先计算: bugs设置为100。 nul_字节被设置

问题是在最后三个语句1、2和3中到底发生了什么。在机器级别内部发生的事情。打印时%s将其视为null、%d将其视为0、%c将其视为无


有人能从机器层面的深度来解释这些吗?

首先:这与机器层面无关。这里的一切都发生在运行时,或者更具体地说,发生在printf的实现中。此外,使用错误的格式说明符进行的所有转换都可能会带来麻烦,因为如果您没有将参数强制转换为格式说明符的正确类型,则无法保证这些转换实际上是正确传递/读取/解释的(例如,由于长度不同)

首先计算:

bugs设置为100。 nul_字节被设置为0 \0的实际值。 care_percentage基本上解决了100*0的问题,这将再次成为0。 那么,会发生什么

第一种情况:这是一种特殊情况,我不一定指望它会这样做。实际上,您正在访问存储在0x00000000的字符串,这将是一个无效位置;可怕的空指针,你很幸运它被抓到了。不要认为它实际上是定义的行为,但请随意证明我错了

第二种情况:传递的值被读取为一个整数,因此它是0,因为这是实际值——想象一下在那里发生的指针转换


第三种情况:传递的值作为一个字符读取,这在这里触发一个特殊情况,因为它不是作为\0直接插入字符串中。

首先:这与机器级别无关。这里的一切都发生在运行时,或者更具体地说,发生在printf的实现中。此外,使用错误的格式说明符进行的所有转换都可能会带来麻烦,因为如果您没有将参数强制转换为格式说明符的正确类型,则无法保证这些转换实际上是正确传递/读取/解释的(例如,由于长度不同)

首先计算:

bugs设置为100。 nul_字节被设置为0 \0的实际值。 care_percentage基本上解决了100*0的问题,这将再次成为0。 那么,会发生什么

第一种情况:这是一种特殊情况,我不一定指望它会这样做。实际上,您正在访问存储在0x00000000的字符串,这将是一个无效位置;可怕的空指针,你很幸运它被抓到了。不要认为它实际上是定义的行为,但请随意证明我错了

第二种情况:传递的值被读取为一个整数,因此它是0,因为这是实际值——想象一下在那里发生的指针转换


第三种情况:传递的值以字符形式读取,这会在此处触发一个特殊情况,因为它不是作为\0直接插入字符串中。

最好对各种数据类型使用正确的格式字符串,这样您将始终获得预期的结果。如果转换规范无效,则行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义。-C11最终草案,§7.21.6.1.9最好对各种数据类型使用正确的格式字符串,这样您将始终获得预期结果。如果转换规范无效,则行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义。-C11最终草案,§7.21.6.1.9 printf的某些POSIX实现以安全的方式处理空指针,如果转换说明符为%s,则打印空指针。AFAIK glibc中的格式引擎是这样实现的。不过这不是标准的。@Mario非常感谢我在艰苦学习C时的回复。第二种情况是好的。我得到它并接受它第一个案例它刚打印出来,这意味着你应该关心null%。为什么这个null突然出现在这里第三个案例打印出来,这意味着你应该关心%。它不会在第一次出现\0@Mario克:不,它不应该被切断。\0未嵌入格式字符串中。格式字符串仅用于以某种方式解释相应的参数。并且%c打印nul字符i。E它不打印任何内容,然后继续打印格式字符串的其余部分。@H2CO3:此外,当传递给printf时,care_percentage被提升为int,但%s从堆栈中取出一个指针,因此参数大小不匹配,行为未定义。@larsmans是的,这就是为什么对这里发生的任何事情进行推理是毫无意义的。。。但是有些人喜欢假设,你知道。printf的一些POSIX实现以安全的方式处理空指针,如果转换说明符是%s,则打印空指针。AFAIK glibc中的格式引擎是这样实现的。不过这不是标准的。@Mario非常感谢您在这段时间内的回复
我在艰难地学习C。第二种情况是好的。我得到它并接受它第一个案例它刚打印出来,这意味着你应该关心null%。为什么这个null突然出现在这里第三个案例打印出来,这意味着你应该关心%。它不会在第一次出现\0@Mario克:不,它不应该被切断。\0未嵌入格式字符串中。格式字符串仅用于以某种方式解释相应的参数。并且%c打印nul字符i。E它不打印任何内容,然后继续打印格式字符串的其余部分。@H2CO3:此外,当传递给printf时,care_percentage被提升为int,但%s从堆栈中取出一个指针,因此参数大小不匹配,行为未定义。@larsmans是的,这就是为什么对这里发生的任何事情进行推理是毫无意义的。。。但是有些人喜欢假设,你知道。
#include<stdio.h>
#include<stdlib.h>
int main( int argc ,char** argv) {
    int bugs = 100;
    char nul_byte='\0';
    char care_percentage = bugs * nul_byte;
    printf("Which means you should care %s%%.\n",care_percentage);// 1->prints (null)
    printf("Which means you should care %d%%.\n",care_percentage);// 2->prints 0
    printf("Which means you should care %c%%.\n",care_percentage);// 3->prints 
    return 0;
}