【 C 】关于相邻字符串常量自动合并的标准(新旧标准)(新旧风格)(陷阱)

举报
李锐博恩 发表于 2021/07/15 07:52:04 2021/07/15
【摘要】 如果一个字符串太长了,我们需要把它分行来写,旧式风格是这样来做的: 1 #include<stdio.h> 2 #include<stdlib.h> 3 int main() 4 { 5 printf( "I love you not because of \ 6 who you are, but because of \ 7 who...

如果一个字符串太长了,我们需要把它分行来写,旧式风格是这样来做的:


  
  1. 1 #include<stdio.h>
  2. 2 #include<stdlib.h>
  3. 3 int main()
  4. 4 {
  5. 5 printf( "I love you not because of \
  6. 6 who you are, but because of \
  7. 7 who I am when I am with you.\n"
  8. 8 );
  9. 9 return 0;
  10. 10 }
  11. 11

编译并运行得到如下结果:

这是什么鬼呀,虽然也得到了结果,可是这显示的也太出乎意料了吧。哪位大佬知道,可以告诉我哪里出问题了。

ANSI C引入的另一种新特性是相邻的字符串常量将被自动合并成一个字符串的约定。这就省掉了过去在书写多行信息时必须在行末加"\"的做法。

现在用一连串的字符串常量来代替它,它们会在编译时自动合并。除了最后一个字符串外,其余每个字符串末尾的NUL字节('\0')会被自动删除。如下:

新式风格:


  
  1. 1 #include<stdio.h>
  2. 2 #include<stdlib.h>
  3. 3 int main()
  4. 4 {
  5. 5 printf( "I love you not because of "
  6. 6 "who you are, but because of "
  7. 7 "who I am when I am with you.\n"
  8. 8 );
  9. 9 return 0;
  10. 10 }
  11. 11

Linux下编译运行结果如下:

显示的还不错。

然而,这种自动合并意味着字符串数组在初始化时,如果不小心漏掉一个逗号,编译器将不会发出错误信息,而是悄无声息地把两个字符串合并在一起。这在下面的例子中引起可怕的后果:


  
  1. 1 #include<stdio.h>
  2. 2 #include<stdlib.h>
  3. 3 #include<string.h>
  4. 4
  5. 5 int main()
  6. 6 {
  7. 7 char *available_resource[] = {
  8. 8 "reborn lee",
  9. 9 "Soul Da",
  10. 10 "vickey"//这里少了一个逗号!
  11. 11 "dog",
  12. 12 "mouse",
  13. 13 "keyboard",
  14. 14 "family", //这个逗号会引起什么问题吗?
  15. 15 };
  16. 16
  17. 17 char *src = malloc( 20 * sizeof( char ) );
  18. 18 if(src != NULL)
  19. 19 strcpy( src, available_resource[3] );
  20. 20 else
  21. 21 printf( "memory allocation false!\n" );
  22. 22
  23. 23 printf( "I love %s\n", available_resource[2] );
  24. 24 // strcpy( src, available_resource[3] );
  25. 25 printf( "puppy is a name of %s\n", src );
  26. 26 free( src );
  27. 27 return 0;
  28. 28 }
  29. 29

结果如下:

root@reborn-pc:~# vim test.c
root@reborn-pc:~# gcc test.c
root@reborn-pc:~# ./a.out
I love vickeydog
puppy is a name of mouse
root@reborn-pc:~#

 

上面的这段程序中,我们很容易发现,第三个字符串后少了一个逗号,这样的话,按照ANSI C标准,就会自动的把它和下一个字符串合成一个字符串,所以呢?如果我们想要得到第三个字符串的内容,本来使用available_resource[2]打印出来就可以了,正如上例中的语句:

 23     printf( "I love %s\n", available_resource[2] );

本来我想说的是:I love vickey,但是结果却打印成了:I love vickeydog,这样,如果vickey是我的女朋友,她看到岂不是误会我骂她,所以不能疏忽!

同样,这条语句:

 19         strcpy( src, available_resource[3] );

 25     printf( "puppy is a name of %s\n", src );

我想表达的是puppy is a name of dog,但是由于那个逗号的遗忘,意思也变了,打印出来的字符串变成了:puppy is a name of mouse

我的天呀,意思千差万别,puppy怎么会是一个老鼠的名字。我家的宠物狗叫puppy好吧。

哈哈,通过上面貌似扯淡的讨论,其实道出了一个问题,就是如果忘掉了一个逗号,编译器也不会报错,但是得到的答案却千差万别,所以要谨防这种问题的出现。

最后需要说的是,程序中的最后一个字符串后面的逗号:

 14         "family",  //这个逗号会引起什么问题吗?

这个地方有没有问题呢?

其实是没有问题的,你也不要怀疑作者是不是多打了一个逗号,事实上,它并不是一个错误,而是从最早的C语法中继承下来的东西,不管存在与否都没有意思!所以见怪不怪吧!

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/82824494

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。