0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

字符串常量的定义与引用

AGk5_ZLG_zhiyua 来源:未知 作者:佚名 2017-09-14 11:37 次阅读

周立功教授数年之心血之作《程序设计与数据结构》

第一章为程序设计基础,本文为1.8.2 字符串常量。

>>>>

1.8.2字符串常量

字符的真正价值在于你可以将它们串在一起形成一个字符序列,即字符串常量,简称字符串。字符串常量就是使用一对双引号“""”包围起来的,以空字符NUL(null character,NUL表示为'\0',ASCII码值为0x00)结尾的连续的字符串,其长度为字符串的长度加1。既然使用空字符结束字符串,那么printf()和strcpy()都将这一点作为默认的前置条件。

注意,NULL和NUL是不同的,NULL表示特殊的指针,通常定义为((void *)0),而NUL是一个char,定义为\0,两者不能混用。虽然字符常量是由单引号引起来的字符序列,通常由一个字符组成,但也可以包含多个字符,比如,转义字符,在C中它们的类型是int:

printf("%d\n", sizeof(char));

printf("%d\n", sizeof('a'));

执行上述代码可以看到char的长度为1,而字符常量的长度为4。

只要在程序中使用字符串,就必须确定如何声明保存字符串的变量。如果将它声明为数组,则编译时就已经为各个字符保留了内存空间;如果将它声明为指针,则编译时完全没有为字符分配任何内存,仅在运行时分配空间。比如:

char cStr[4] = "OK!";

char *pcStr = "OK!";

两者的区别是,数组名cStr是常量,而指针名pcStr是变量。注意,如果在初始化指针之前就使用指针,有可能会导致运行出错,如果有以下定义:

char *pcStr;

printf("%s", *pcStr);

由于这里没有对pcStr初始化,因此其指向的内存是未知的,将会打印出奇怪的字符,于是pcStr自然也就成为了野指针。

>>>1.字符串的引用

由于"OK!"是一个字符串常量,因此是不可修改的。如果试图执行以下操作:

pcStr[2] = 'Z';

虽然编译期可以通过,但在运行时会出错。如果以下面这样的形式赋值:

char cStr[4];

cStr = "OK!";

则是非法的,因为数组变量名cStr是一个不可修改的常量指针。

如果字符数组中没有保存'\0'',它仅仅是字符常量'O'、'K'、'!',不是字符串。即:

char cStr[] = { 'O', 'K', '!'};

而“char cStr[] = "OK!";”只不过是“char cStr[] = {'O', 'K', '!', '\0'};”的另一种写法,因为字符串是一种特殊的字符数组变量,所以其存储方式与数组变量一致。其中的cStr为数组变量名,表示此数组第0个元素的地址(即&cStr[0]),cStr+1表示数组第1个元素的地址(即&cStr[1]),cStr+2表示数组变量第2个元素的地址(即&cStr[2]),cStr+3表示数组变量第3个元素的地址(即&cStr[3]),其存储形式详见图1.13。

图1.13 “OK!”的存储形式

C语言中的字符串是以字符数组变量的形式处理的,具有数组的属性,所以不能赋值给整个字符数组变量,只能将字符逐个赋给字符数组变量。比如:

char cStr[4];

cStr[0] = 'O'; cStr[1] = 'K'; cStr[2] = '!'; cStr[3] = '\0';

其存储的不是字符本身,而是以ASCII码存储的字符常量(即存值)。

惯用法

由于字符串常量以'\0'(ASCII码值为0x00)结尾,因此可以用cStr[i]作为for循环语句的“条件部分(布尔表达式)”,检查cStr[i]是否为'\0'(cStr[i]是以*(cStr+i)形式表示的)。用于处理字符串中每一个字符的惯用法如下:

for(i = 0; cStr[i] != '\0'; i++) …

其等价于

for(i = 0; cStr[i]; i++) …

同理“while(cStr[i] != '\0')”与“while(cStr[i])”是等价的。

当然,也可以使用scanf()函数的%s格式声明符输入字符串,详见程序清单 1.37。

程序清单1.37字符串的输入与输出范例程序

1 #include

2 int main(int argc, char *argv[])

3 {

4 char cStr[10];

5

6 scanf("%s", cStr);

7 printf("%s", cStr);

8 return 0

9 }

由于cStr代表字符数组的起始地址,因此不需要在cStr前添加&运算符。但采用%s格式符输入字符串存在一种潜在危险,如果输入的字符串太长,超出了字符数组的存储极限,则程序执行错误,因此可以使用“字段宽度”来限制输入字符串的长度更安全。

由于字符串常量的类型是char的数组,则在表达式中被解读为指针。即不管字符串有多长,pcStr始终存储字符串第一个字符的地址,因此使用指向字符串的指针变量即可整体引用一个字符串。比如:

char *pcStr = "OK!";

其中的pcStr是字符指针变量,其等效于

static const char t376[] = "OK!";

char *pcStr = t376;

其中的t376是编译器分配的一个内部变量名,不同编译器、不同程序、甚至同一个源代码每次编译,其名字均可能不同。显然,程序员不知道这个数组的名字,即匿名数组变量。显而易见,初始化字符数组存储字符串和初始化指针指向字符串的区别在于,数组名是常量,而指针名是变量,因此字符串的绝大多数操作都是通过指针完成的。

由此可见,"OK!"就是“char的数组”,通过sizeof("OK!")也可以证明字符串的本质还是数组,即可用"OK!"作为数组变量名,详见程序清单 1.38。

程序清单1.38用字符串作为数组变量名范例程序

1 #include

2 int main(int argc, char argv *[])

3 {

4 printf("OK!占用的空间%d", sizeof("OK!")); // 输出"OK!"占用的空间,即4个字节

5 printf("OK!的地址%x\n", "OK!");// 输出"OK!"的地址

6 printf("%c\n", *("OK!" + 1)); //输出"OK!"的第1个元素,即'K'

7 printf("%c\n", "OK!"[0]); //输出"OK!"的第0个元素,即'O'

8 printf("%d\n", "OK!"[3]); //输出"OK!"第3个元素的值,即'\0'

9 return 0;

10 }

由于C语言允许对指针添加下标,因此程序清单 1.38(6~8)分别输出对应的元素。显然,可以利用这种方式将0~15转换为等价的16进制的字符,详见程序清单 1.39。

程序清单1.39 digit_to_charhex()转换函数范例程序

1 char digit_to_hexchar(int digit)

2 {

3 return "0123456789ABCDEF"[digit];

4 }

当pcStr指向字符串"OK!"的首地址时,*pcStr表示该地址空间上的值为'O',即pcStr[0]= 'O',pcStr[1]= 'K',pcStr[2]= '!',pcStr[3]= '\0',或*pcStr='O',*(pcStr+1)='K',*(pcStr+2)='!',*(pcStr+3)= '\0'。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 字符串
    +关注

    关注

    1

    文章

    585

    浏览量

    20622

原文标题:周立功:字符真正价值在于形成字符序列——字符串的引用

文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    周立功《程序设计与数据结构》:字符串函数

    本文为程序设计基础,本文为1.8.2 字符串常量第三点:字符串函数。
    的头像 发表于 09-05 09:18 5669次阅读

    字符串常量的接线端如何反向

    本帖最后由 209巨子 于 2016-7-23 21:35 编辑 我是新手,这几天才开始学习LabVIEW,求助各位大神,字符串常量的接线端是如何反向的?或者说,下图中真常量字符串
    发表于 07-23 21:34

    字符串数组常量乱码,如何解决

    字符串数组常量输入英文后,整个数组乱码了如果数组全是中文是没问题的,添加一个英文的字符后都乱码
    发表于 04-06 15:53

    数组、向量和字符串 实验

    实验 5 数组、向量和字符串一、实验目的 1. 掌握Java中的数组定义引用2. 掌握向量的基本概念和应用技术3. 掌握使用字符串String类
    发表于 09-23 19:00 1564次阅读

    C语言入门教程-字符串须知

    字符串须知 关于字符串常量假设您编写并运行下面两段代码: printf("%s ",s);} Fragment 2 {char s[100];strcpy(s,"hello");printf("%s ",s);}
    发表于 07-29 14:19 1186次阅读

    LabVIEW的常用字符串操作教程免费下载

    。主要包括常用工具字符串函数、字符串常量字符串/数值转换、字符串/数组/路径转换和附加字符串
    发表于 08-21 14:51 26次下载
    LabVIEW的常用<b class='flag-5'>字符串</b>操作教程免费下载

    2.2 python字符串类型

    2.2 python字符串类型 1. 如何定义字符串字符串是Python中最常用的数据类型之一。 使用单引号或双引号来创建字符串,使用三
    的头像 发表于 02-17 17:08 1486次阅读

    字符串函数重写练习

    字符串函数重写练习:字符串比较、字符串拼接、字符串查找、字符串拷贝、内存比较、内存拷贝、内存初始化、内存比较、二维数组
    的头像 发表于 05-05 15:02 2052次阅读

    Java反射机制清空字符串导致业务异常分析

    JVM为了提高性能和减少内存开销,在实例化字符串常量时进行了优化。JVM在Java堆上开辟了一个字符串常量池空间(StringTable),JVM通过ldc指令加载
    的头像 发表于 06-22 11:17 1071次阅读

    C语言总结_字符串函数封装练习

    字符串函数重写练习:字符串比较、字符串拼接、字符串查找、字符串拷贝、内存比较、内存拷贝、内存初始化、内存比较、二维数组
    的头像 发表于 08-14 09:42 1064次阅读

    格式化字符串常量f-strings一些不常见的特性

    【导语】:本文介绍了“格式化字符串常量”f-strings一些不常见的特性,包括:格式化日期和时间、同时打印变量名和变量值等,嵌套使用f-strings等,此外与其他格式化字符串的方法相比,f-strings的速度更快,因此,学
    的头像 发表于 08-15 12:00 1213次阅读

    C语言字符数组和字符串有什么区别

    用来存放字符的数组称为字符数组。字符数组的各个元素依次存放字符串的各字符,字符数组的数组 名代表
    的头像 发表于 02-17 14:27 3913次阅读

    C语言字符串引用方式

    在C语言程序中,字符串是存放在字符数组中的。 2. 用字符数组存放一个字符串,可以通过数组名和下标引用字符串中的一个
    的头像 发表于 03-10 14:57 2018次阅读

    C语言定义字符串的几种方法

    C语言中定义字符串有哪些方法?
    的头像 发表于 03-31 09:41 3688次阅读

    c语言字符串定义

    字符串定义、初始化、操作和常见问题。 字符串定义和初始化 在C语言中,字符串定义为一个
    的头像 发表于 11-24 10:02 2156次阅读