当我这样做时会发生什么?
{
char * str = "%d\n";
str++;
str++;
printf(str-2,300);
return 0;
}
直观地说,屏幕上的数字似乎是300,但我想知道,什么存储在str。
编辑:如果有人能告诉我,我们什么时候真的这样做会很棒? 谢谢!
答案 0 :(得分:3)
str
是一个内存地址,最初是字符串文字%
的{{1}}符号的地址。创建此文字是因为它在您的代码中。
两个增量使str指向字符%d\n
,在这种情况下,\n
是str - 2
符号的地址。因此printf看到格式字符串%
,并且像往常一样将格式字符串后的第一个参数打印为整数。事实是,printf并不关心格式字符串的来源。如果您可以即时创建它,或者对其进行硬编码也无关紧要。
我们一般都不这样做。有时你需要摆弄一个字符指针来扫描字符串,从字符串中提取一些东西,或者跳过一些字符串的前缀。
答案 1 :(得分:2)
嗯,你正在声明一个char指针。该指针将保存RAM
地址,您将在其中写入以下字节:%
(1字节)d
(1字节)\n
(UNIX上为1字节,2字节)在Windows上)和\0
结束字符串的空终止字节。
然后将指针值(即第一个字节的地址)递增2,然后递减2。所以基本上你什么都不做。因此,当调用printf()
src-2
将指向%d\n
时,空终止字节将使其完全通过%d\n
。
所以在一天结束时你所做的是:
printf("%d\n", 300);
因此300输出。
答案 2 :(得分:2)
str
是堆栈上的指针。它最初指向(即保存地址)字符串文字"%d\n"
的开头(这可能由编译器存储在程序的只读部分中)。
让我们说例如字符串文字("$d\n"
)存储在0x5000。因此(假设为UTF-8或ASCII)0x5000处的字节为%
,0x5001处的字节为d
,0x5002为\n
(换行符),而0x5003为{{1} (终止空字符)
\0
最初持有地址0x5000。 str
会将其增加到0x5001,这意味着它现在指向字符串str++
,即字符串文字"d\n"
中的一个字符。同样,"%d\n"
再次将其移动到0x5002,即字符串str++
,将两个字符移动到字符串文字"\n"
中。请注意,所有这些仍然由0x5003处的空字符终止(C知道字符串何时结束)。
"%d\n"
调用将格式字符串作为第一个参数。此时printf
保留0x5002,因此调用是说'使用从str
&#39;开始的格式字符串,结果与我们开始时的字符串相同。< / p>
因此它与调用
相同0x5002 - 2 = 0x5000
并将打印出300。