我对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?
答案 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字符串。