在指针中存储格式说明符

时间:2014-07-20 05:05:45

标签: c pointers

当我这样做时会发生什么?

{ 
  char * str = "%d\n";
  str++;
  str++;
  printf(str-2,300);
  return 0;
}

直观地说,屏幕上的数字似乎是300,但我想知道,什么存储在str。

编辑:如果有人能告诉我,我们什么时候真的这样做会很棒? 谢谢!

3 个答案:

答案 0 :(得分:3)

str是一个内存地址,最初是字符串文字%的{​​{1}}符号的地址。创建此文字是因为它在您的代码中。

两个增量使str指向字符%d\n,在这种情况下,\nstr - 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,因此调用是说&#39;使用从str&#39;开始的格式字符串,结果与我们开始时的字符串相同。< / p>

因此它与调用

相同
0x5002 - 2 = 0x5000

并将打印出300。