【 C 】字符串常量
当一个字符串常量出现在表达式中时,它的值是个指针常量。编译器把这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。但是,当数组名用于表达式中时,它们的值也是个指针常量。我们可以对它们进行下标引用、间接访问以及指针运算。
这些操作对于字符串常量是不是也有意义呢?
看看下面这个表达式是什么意思?
"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时:
各位自行总结规律!
各位大侠如果觉得这个例子垃圾,那我们就再看一个例子:
这个例子在递归函数中也见过,非常好玩!
贴出来代码:
//接受一个整型值(无符号),把它转换为字符并打印它。
#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 】字符串常量的更多相关文章
- 使用Microsoft Roslyn提取C#和VB.NET源代码中的字符串常量
Microsoft Roslyn是微软.NET“编译器即服务(Compiler as a Service)”的主要产品,它提供了开放的编译器API,并为源代码产生.分析和重构提供了新一代的语言对象模型 ...
- Java字符串常量池
JVM为了减少字符串对象的重复创建,维护了一个特殊的内存,这段内存被称为字符串常量池. Java中字符串对象的创建有两种形式:一种是字面量形式,String str = "a":一 ...
- 字符数组,字符指针,字符串常量,以及sizeof的一些总结
1.以字符串形式出现的,编译器都会为该字符串自动添加一个\0作为结尾 如在代码中写"abc",编译器帮你存储的是"abc\0". 2.数组的类型是由该数组所存放 ...
- Java中的字符串常量池
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...
- C++字符串常量
C++字符串常量 当一个字符串常量出现于表达式中时,它的值是个指针常量.编译器把这个指定字符的一份copy存储在内存的某个位置(全局区),并存储一个指向第一个字符的指针. #include <i ...
- PostgreSQL中美元符号引用的字符串常量
虽然用于指定字符串常量的标准语法通常都很方便,但是当字符串中包含了很多单引号或反斜线时很难理解它,因为每一个都需要被双写.要在这种情形下允许可读性更好的查询,PostgreSQL提供了另一种被称为“美 ...
- Python学习总结4:字符串常量与操作汇总
参考博客:http://www.cnblogs.com/Camilo/archive/2013/09/21/3332267.html http://www.cnblogs.com/SunWentao/ ...
- C++常量(C++数值常量、字符串常量、符号常量)
http://see.xidian.edu.cn/cpp/biancheng/view/104.html 字符串常量 用双撇号括起来的部分就是字符串常量,如"abc"," ...
- 字符串常量演示Demo
public class StringDemo { public static void main(String[] args) { // TODO Auto-generated method stu ...
- C语言中字符串常量到底存在哪了?
常量存储总结局部变量.静态局部变量.全局变量.全局静态变量.字符串常量以及动态申请的内存区 1.局部变量存储在栈中2.全局变量.静态变量(全局和局部静态变量)存储在静态存储区3.new申请的内存是在堆 ...
随机推荐
- 重装win7系统的过程
U盘重装系统准备工作: 1.下载一个制作U盘系统的软件,随便哪个都行,把U盘变成系统盘 2.下载镜像,将镜像copy到系统盘内即可(无需解压) 3.进入BIOS系统,将boot进行设置,将U盘设置为第 ...
- python 使用set对列表去重后,保持原来列表的顺序排列
testlist = ['cc', 'bbbb', 'afa', 'sss', 'bbbb', 'cc', 'shafa'] set2list = list(set(testlist)) print ...
- 实用的 CSS 小片段
看了 30 Seconds CSS,有了许多收获,所以写下了这篇文章,算是收藏一些代码小片段,留作后用. 一.手写 Loading 动画 (1)弹性加载动画 CSS 代码如下: .bounce-loa ...
- IntelliJ IDEA 下载和激活
IntelliJ IDEA 下载地址: https://www.jetbrains.com/idea/download/#section=windows 激活码获取地址:http://idea.lan ...
- 随手练——HDU-1210 洗牌问题(模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1210 模拟的题目真不知道怎么写的话,就把真实情况展示出来,有图才有真相: 测试代码: #include ...
- Spyder中figure显示设置
Spyder是Python的一个IDE.和其他的Python的IDE相比,它最大的优点就是模仿MATLAB的“工作空间”的功能,可以很方便地观察和修改数组的值. 如果不是进行大规模的工程开发,重点专注 ...
- 提交json串格式的POST请求
提交json串格式的POST请求 Action() { web_reg_save_param("retCode", "LB=retCode\":\"& ...
- djb2:一个产生简单的随机分布的哈希函数
目录 LCG算法 示例代码 djb2 示例代码 为什么选择参数33和 33 was chosen because: 5381 was chosen because 哈希选择参考 LCG算法 djb2与 ...
- linux系统安装redis服务器与php redis扩展
一 安装redis服务 1更新yum源 CentOS/RHEL 7.x: rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-lat ...
- Java 常用IO流操作详解
1.基本概念 IO:Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输,上传文件和下载文件,Java用于操作流的对象都在IO包中. 2.IO流的分类 图示:(主要IO流) 3.字节流 ...