一道有争议的C语言题
题目如下,找出代码中错误的地方,并改正。
#include
#include
#include
int main()
{char a;char *str=&a;strcpy(str,"hello");printf(str);return 0;
}
我个人认为有3个错误。
a 是个字符型变量,只能存储1个字符。并且,没有为str分配内存空间,将一个字符串复制进一个字符变量指针所指 地址。会因为越界进行内在读写而导致程序崩溃。
应该改为如下的形式。
char a[6];
char *str=a;
有争议的地方是 printf(str); 。第一次见这种用法,第一反应是不对的。
不过,上网查了下,这种用法有时候也可以输出正确的结果,但不建议大家这么用。
GCC编译时也会有警告,提示没有格式化参数。
warning: format not a string literal and no format arguments [-Wformat-security]
这种用法其实跟printf("hello,world.\n")是类似的,printf函数的第一个参数是const char*类型的,不管是printf("abcd")还是printf(str),效果都是一样的,就是像printf函数传递了一个const char*的地址,然后printf按照这个地址打印出里面的内容。
可参考man里面的printf:
SYNOPSIS\#include intprintf(const char *format, ...);intfprintf(FILE *stream, const char *format, ...);
只是const char *p = "hello, world"以后再printf(p)跟printf("%s", p)的效果是一样的,但平常为什么不见printf(p)这种看起来很简洁的形式呢?
看下这个例子
#include
int main(void)
{char *str = "A string with % may not work.\n";printf("%s", str);printf(str);char *str2 = "i want to print %d\n";printf("%s", str2);printf(str2);return 0;
}
gcc编译输出的结果是:
A string with % may not work.
A string with Successay not work.
i want to print %d
i want to print 134513794。
输出结果出现了乱码,%变成了Successay,%d变成了134513794这串数字。
由于printf支持可变参数,所以后续变量的个数就需要通过str中的格式化串来确定。当str串中包含%s,%d,%c等格式化串时,printf就会去栈中找这个格式化串对应的变量,但实际上,根本没有向printf压入更多的参数,因此就会出现打印失败或者程序崩溃的现象。
所以最好不要直接使用printf(str),会出现意想不到的结果。
【公众号】:奇牛编程
【C语言】五小时快速入门C语言:【C语言】五小时快速入门C语言
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
