1

我在 c 编程方面有比较好的经验。它一直是我最喜欢的语言之一。今天在学习 shell 编程时,偶然发现了我在 Linux 系统上执行的 ac 程序(Backtrack 5 r2)。该程序有一个奇怪的输出,我真的想不通。

这是代码...

#include <stdio.h>

int main(int argc, char *argv[])
{
    char array[] = { 0x25, 115, 0 };
    char array2[] = { 68, 0x61, 118, 0x69, 0144, 040,
                      0107, 97, 0x74, 119, 0157, 0x6f,
                      100, 0x20, 0x72, 117, 'l', 0x65,
                      115, 041, 012, 0 };

    printf(array, array2);
}

使用 gcc 编译此代码并在执行时得到输出为

大卫盖特伍德规则!

无法真正理解我是如何以及为什么得到这个输出的。据我所知,将数组的名称传递给“printf”只会打印数组的基地址,即数组第 0 个元素的地址。只有在“printf”语句中使用了正确的格式说明符时,它才会正确显示。

那么我哪里出错了,或者我忽略了一些重要的事情,还是因为 gcc?

4

3 回答 3

4

认为array作为"%s"。因此printf打印一个字符串。

ASCII 0x25: %
ASCII 115:  s

也一样array2。我不确定为什么作者混合了十进制十六进制和八进制。

于 2013-03-02T07:57:48.053 回答
3

这个程序只是一种混淆的写法

#include <stdio.h>

int main(int argc, char *argv[])
{
    char array[] = { '%', 's', '\0' };
    char array2[] = { 'D', 'a', 'v', 'i', 'd', ' ', ..., '\0' };

    printf(array, array2);
}

由于 printf 期望格式为字符串,并且在这样的表达式中使用的数组名称被视为(“衰减”,尽管该术语不是官方标准术语)指向其第一个元素的指针,所以一切都是正确的。事实上,初始化等价于

char *array = "%s";
char *array2 = "David ...";

除了后者不可写(因为字符串文字在 C 中是只读的)。

不,将数组传递给 printf (到底在哪里?)不会打印它的地址。打印数组地址(或指针)只能使用%p转换说明符:

printf ("array/ptr address = %p\n", (void *)array);

请注意,需要(void *)强制转换以避免未定义的行为。

于 2013-03-02T08:42:26.450 回答
0

当您这样做时,您还期望什么printf("%s", "David Gatwood rules!"); 正如您所写的,您有使用 c 的经验,您还应该看到指向 char 数组的指针,其中字符用作 c 字符串。

于 2013-03-02T12:43:02.197 回答