c程序有奇怪的输出

时间:2013-03-02 07:56:28

标签: c arrays

我对c编程有相对较好的经验。它一直是我最喜欢的语言之一。今天在学习shell编程时,我遇到了一个我在Linux系统上执行的程序(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编译此代码,执行时输出为

  

David Gatwood规则!

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

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

3 个答案:

答案 0 :(得分:4)

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

ASCII 0x25: %
ASCII 115:  s

同样适用于array2。我不确定为什么作者会混合十进制十六进制和八进制。

答案 1 :(得分: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 *)强制转换 以避免未定义的行为。

答案 2 :(得分:0)

当你printf("%s", "David Gatwood rules!");时,你还会有什么期待? 正如你所写的那样,你有c的经验,你应该看到char数组的指针,字符用作c字符串。