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

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

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

"xyz" + 1

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

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

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

*"xyz"

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

我们继续放出大招:

"xyz"[2]

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

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

*( "xyz" + 4 )

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

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

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

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

#include <stdio.h>

void mystery( int n )
{
n += 5;
n /= 10;
printf("%s\n", "**********" + 10 - n );
}

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

#include <stdio.h>
#define M 6 void mystery( int n )
{
n += 5;
n /= 10;
printf("%s\n", "**********" + 10 - n );
} int main()
{
mystery( M );
return 0;
}

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

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

当输入M = 10 时候:

输入M = 100时:

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

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

【 C 】深入了解递归

贴出来代码:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
unsigned int quotient; quotient = value / 10;
if(quotient != 0)
binary_to_ascii(quotient); putchar(value % 10 + '0'); }

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

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

测试下呗:

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
unsigned int quotient; quotient = value / 10;
if(quotient != 0)
binary_to_ascii(quotient); putchar(value % 10 + '0'); } int main()
{
binary_to_ascii(16); return 0;
}

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

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
unsigned int quotient; quotient = value / 16;
if(quotient != 0)
binary_to_ascii(quotient); putchar( "0123456789ABCDEF"[value % 16] ); } int main()
{
binary_to_ascii(26); return 0;
}

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

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

//接受一个整型值(无符号),把它转换为字符并打印它。

#include <stdio.h>

void binary_to_ascii(unsigned int value)
{
unsigned int quotient, remainder; quotient = value / 16;
if(quotient != 0)
binary_to_ascii(quotient); remainder = value % 16;
if( remainder < 10 )
putchar( remainder + '0' );
else
putchar( remainder - 10 + 'A' ); } int main()
{
binary_to_ascii(26); return 0;
}

【 C 】字符串常量的更多相关文章

  1. 使用Microsoft Roslyn提取C#和VB.NET源代码中的字符串常量

    Microsoft Roslyn是微软.NET“编译器即服务(Compiler as a Service)”的主要产品,它提供了开放的编译器API,并为源代码产生.分析和重构提供了新一代的语言对象模型 ...

  2. Java字符串常量池

    JVM为了减少字符串对象的重复创建,维护了一个特殊的内存,这段内存被称为字符串常量池. Java中字符串对象的创建有两种形式:一种是字面量形式,String str = "a":一 ...

  3. 字符数组,字符指针,字符串常量,以及sizeof的一些总结

    1.以字符串形式出现的,编译器都会为该字符串自动添加一个\0作为结尾 如在代码中写"abc",编译器帮你存储的是"abc\0". 2.数组的类型是由该数组所存放 ...

  4. Java中的字符串常量池

    ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...

  5. C++字符串常量

    C++字符串常量 当一个字符串常量出现于表达式中时,它的值是个指针常量.编译器把这个指定字符的一份copy存储在内存的某个位置(全局区),并存储一个指向第一个字符的指针. #include <i ...

  6. PostgreSQL中美元符号引用的字符串常量

    虽然用于指定字符串常量的标准语法通常都很方便,但是当字符串中包含了很多单引号或反斜线时很难理解它,因为每一个都需要被双写.要在这种情形下允许可读性更好的查询,PostgreSQL提供了另一种被称为“美 ...

  7. Python学习总结4:字符串常量与操作汇总

    参考博客:http://www.cnblogs.com/Camilo/archive/2013/09/21/3332267.html http://www.cnblogs.com/SunWentao/ ...

  8. C++常量(C++数值常量、字符串常量、符号常量)

    http://see.xidian.edu.cn/cpp/biancheng/view/104.html 字符串常量 用双撇号括起来的部分就是字符串常量,如"abc"," ...

  9. 字符串常量演示Demo

    public class StringDemo { public static void main(String[] args) { // TODO Auto-generated method stu ...

  10. C语言中字符串常量到底存在哪了?

    常量存储总结局部变量.静态局部变量.全局变量.全局静态变量.字符串常量以及动态申请的内存区 1.局部变量存储在栈中2.全局变量.静态变量(全局和局部静态变量)存储在静态存储区3.new申请的内存是在堆 ...

随机推荐

  1. pythone 请求响应字典

    _RESPONSE_STATUSES = { # Informational 100: 'Continue', 101: 'Switching Protocols', 102: 'Processing ...

  2. HDFS 读取、写入、遍历文件夹获取文件全路径、append

    版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/37573081 1.从HDFS中 ...

  3. 【[JXOI2017]加法】

    江西竟然还有省选,而且还是可怜题,实在是有点可怕 这道题还是比较清真的,大概是最简单的可怜题? 首先看到最大值最小,就很容易想到了二分答案 对于一个二分出来的答案\(mid\),去把原数列扫一遍就可以 ...

  4. Java50道经典习题-程序13 根据条件求数字

    题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?分析:完全平方数:如果一个数能是由两个相同的数相乘的结果,那么这个数就是完全平方数,例如:9==3*3: ...

  5. docker安装后启动不了 解决方法

    第一种情况: 可能是你的selinux没有disabled,导致了守护docker的deamon进程启动不了 查看系统日志如果发现下列信息: May 7 12:34:14 localhost dock ...

  6. [AHOI2001]多项式乘法

    \([Link](https://www.luogu.org/problemnew/show/P2553)\) \(\color{red}{\mathcal{Description}}\) 给出两个多 ...

  7. Selenium自动化测试值环境搭建

    Selenium自动化测试之环境搭建 一.背景介绍 自动化测试近几年在测试领域很火,出去面试要是说不会自动化测试薪资都不好意思往高了要!很多公司做敏捷测试用到自动化,其他一些公司也是跟风,即使用不上自 ...

  8. Android攻城狮学习笔记—入门篇一

    第一章 搭建Android开发环境 1.1 环境组成 JDK(Java Development Kit) Eclipse Android SDK(Software Development Kit) A ...

  9. HDU 3339 In Action(迪杰斯特拉+01背包)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=3339 In Action Time Limit: 2000/1000 MS (Java/Others) ...

  10. HDU 1272小希的迷宫(裸并查集,要判断是否构成环,是否是连通图)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1272 小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    ...