【 C 】彻底学会字符串常量

举报
李锐博恩 发表于 2021/07/15 06:48:54 2021/07/15
【摘要】 当一个字符串常量出现在表达式中时,它的值是个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。但是,当数组名用于表达式中时,它们的值也是个指针常量。我们可以对它们进行下标引用、间接访问以及指针运算。 这些操作对于字符串常量是不是也有意义呢? 看看下面这个表达式是什么意思? "xyz" + 1 看上去像是一个垃圾!它好像是试图...

当一个字符串常量出现在表达式中时,它的值是个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。但是,当数组名用于表达式中时,它们的值也是个指针常量。我们可以对它们进行下标引用、间接访问以及指针运算。

这些操作对于字符串常量是不是也有意义呢?

看看下面这个表达式是什么意思?

"xyz" + 1
 

看上去像是一个垃圾!它好像是试图在一个字符串上面执行某种类型的加法运算。

但是,当你记得字符串常量实际上是一个指针常量时,它的意义就变得清楚了。这个表达式计算“指针值 + 1”的值。它的结果是个指针,指向字符串的第二个字符:y。

那么这个表达式又是什么呢?

*"xyz"
 

理解了第一个,后面的都好说:对一个指针执行间接访问时,其结果就是该指针指向的值。字符串常量的类型是指向字符的指针,所以这个间接访问得到的结果是字符‘x’。

我们继续放出大招:

"xyz"[2]
 

很简单,对一个指针进行下标访问是合理的,就像数组名也是一个指针常量,对其下标访问就是对数组中的元素进行访问,这个同理,表达式的值为一个字符‘z’。

下面给出一个错误的例子:

*( "xyz" + 4 )
 

这个表达式的结果是什么呢?

事实上,这是一个错误,它的偏移量4超过了字符串的访问,就像你访问一个数组的元素,超出了索引范围一样,这样有可能会出大事!这个表达式的结果是一个不可预测的值。

什么时候会用到类似这些形式的表达式呢?

《C与指针》给出了一个神秘函数的例子:


  
  1. #include <stdio.h>
  2. void mystery( int n )
  3. {
  4. n += 5;
  5. n /= 10;
  6. printf("%s\n", "**********" + 10 - n );
  7. }

最后一个标准输出语句使用了字符串常量,下面我们测试下这个函数执行的情况:


  
  1. #include <stdio.h>
  2. #define M 6
  3. void mystery( int n )
  4. {
  5. n += 5;
  6. n /= 10;
  7. printf("%s\n", "**********" + 10 - n );
  8. }
  9. int main()
  10. {
  11. mystery( M );
  12. return 0;
  13. }

我们通过改变M的值,来运行这个程序:

大家可在这个网站上实验:https://www.tutorialspoint.com/compile_c_online.php

当输入M = 10 时候:

输入M = 100时:

各位自行总结规律!
各位大侠如果觉得这个例子垃圾,那我们就再看一个例子:

这个例子在递归函数中也见过,非常好玩!

【 C 】深入了解递归

贴出来代码:


  
  1. //接受一个整型值(无符号),把它转换为字符并打印它。
  2. #include <stdio.h>
  3. void binary_to_ascii(unsigned int value)
  4. {
  5. unsigned int quotient;
  6. quotient = value / 10;
  7. if(quotient != 0)
  8. binary_to_ascii(quotient);
  9. putchar(value % 10 + '0');
  10. }

这个例子,如果你不太了解递归函数,恐怕会感到无解!

但它确实能实现把一个整型值转换为字符打印的操作。

测试下呗:


  
  1. //接受一个整型值(无符号),把它转换为字符并打印它。
  2. #include <stdio.h>
  3. void binary_to_ascii(unsigned int value)
  4. {
  5. unsigned int quotient;
  6. quotient = value / 10;
  7. if(quotient != 0)
  8. binary_to_ascii(quotient);
  9. putchar(value % 10 + '0');
  10. }
  11. int main()
  12. {
  13. binary_to_ascii(16);
  14. return 0;
  15. }

 

下面我们对这个例子进行修改,以十六进制的形式打印结果值:


  
  1. //接受一个整型值(无符号),把它转换为字符并打印它。
  2. #include <stdio.h>
  3. void binary_to_ascii(unsigned int value)
  4. {
  5. unsigned int quotient;
  6. quotient = value / 16;
  7. if(quotient != 0)
  8. binary_to_ascii(quotient);
  9. putchar( "0123456789ABCDEF"[value % 16] );
  10. }
  11. int main()
  12. {
  13. binary_to_ascii(26);
  14. return 0;
  15. }

这就很完美了,成功的运用了字符串常量是一个指针常量的意义来设计程序!

当然,如果觉得字符串常量难以理解的话,可以有一个简单的替代方案,但是代码没有字符串常量简洁:


  
  1. //接受一个整型值(无符号),把它转换为字符并打印它。
  2. #include <stdio.h>
  3. void binary_to_ascii(unsigned int value)
  4. {
  5. unsigned int quotient, remainder;
  6. quotient = value / 16;
  7. if(quotient != 0)
  8. binary_to_ascii(quotient);
  9. remainder = value % 16;
  10. if( remainder < 10 )
  11. putchar( remainder + '0' );
  12. else
  13. putchar( remainder - 10 + 'A' );
  14. }
  15. int main()
  16. {
  17. binary_to_ascii(26);
  18. return 0;
  19. }

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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