字符串的存储方式有字符数组和字符指针,我们先来看看字符数组。

因为字符串是由多个字符组成的序列,所以要想存储一个字符串,可以先把它拆成一个个字符,然后分别对这些字符进行存储,即通过字符数组存储。字符数组是一个数组,且是存储字符的数组,该数组中一个元素存放字符串的一个字符。

字符数组的定义

因为字符数组首先是一个数组,所以前面讲的数组内容通通都适用。其次它是存放字符的数组,即数组的类型是 char 型。比如:

  1. char name[10];

表示定义了 10 字节的连续内存空间。

1) 如果字符串的长度大于 10,那么就存在语法错误。这里需要注意的是,这里指的“字符串的长度”包括最后的 '\0'。也就是说,虽然系统会自动在字符串的结尾加 '\0',但它不会自动为 '\0' 开辟内存空间。所以在定义数组长度的时候一定要考虑 '\0'。

2) 如果字符串的长度小于数组的长度,则只将字符串中的字符赋给数组中前面的元素,剩下的内存空间系统会自动用 \0' 填充。

字符数组的初始化

字符数组的初始化与数组的初始化一样,要么定义时初始化,要么定义后初始化。下面写一个程序来说明这个问题:

# include <stdio.h>
int main(void)
{
char a[];
a[] = 'i'; a[] = ' '; a[] = 'l'; a[] = 'o'; a[] = 'v';
//空格字符的单引号内一定要敲空格
a[] = 'e'; a[] = ' '; a[] = 'y'; a[] = 'o'; a[] = 'u';
//空格字符的单引号内一定要敲空格
a[] = '\0';
char b[];
b[] = 'i'; b[] = ' '; b[] = 'm'; b[] = 'i'; b[] = 's';
//空格字符的单引号内一定要敲空格
b[] = 's'; b[] = ' '; b[] = 'y'; b[] = 'o'; b[] = 'u';
//空格字符的单引号内一定要敲空格
char c[] = "i believe you";
char d[] = {'i', ' ', 'l', 'i', 'k', 'e', ' ', 'y', 'o', 'u','\0'};
//空格字符的单引号内一定要敲空格
char e[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};
//空格字符的单引号内一定要敲空格
char f[] = "上课睡觉觉, 下课打闹闹, 考试死翘翘";
char g[] = "";
printf("a = %s\n", a); //输出字符串用%s, 输出参数必须写数组名
printf("b = %s\n", b);
printf("c = %s\n", c);
printf("d = %s\n", d);
printf("e = %s\n", e);
printf("f = %s\n", f);
printf("g = %s\n", g);
return ;
}

输出结果是:

a = i love you
b = i miss you烫i love you
c = i believe you
d = i like you
e = Hello World蘨 like you
f = 上课睡觉觉, 下课打闹闹, 考试死翘翘
g =
mac下输出:


首先要说明的是,这个程序只有在 .cpp 文件中才能运行,在 .c 文件中会有很多错误。因为我们在前面讲过,C89 标准规定变量的定义只能在程序的开头,或者说定义变量的前面不能有其他非声明或非定义的语句。而 .cpp 文件是编写 C++ 程序的,C++ 向下完全兼容 C,而且它对变量定义的位置没有特殊要求,只要在使用位置之前即可。

数组 a 是先定义后初始化。一方面与以前讲的数值型数组一样,先定义后初始化必须一个一个地进行赋值,不能整体赋值;另一方面与以前讲的数值型数组又不一样,对于字符串,先定义后初始化也可以整体赋值,但是要调用 strcpy 函数,这点稍后再讲。

总之上面这个程序中给数组 a 一个一个进行初始化的方式很麻烦。而且这样写需要注意:前面讲过系统会在字符串的最后自动添加结束标志符 '\0',但是当一个一个赋值时,系统不会自动添加 '\0',必须手动添加。如果忘记添加,虽然语法上没有错误,但是程序将无法达到我们想要的功能。数组 b 就是这样的例子。

此外,空格字符必须要在单引号内“敲”一个空格,不能什么都不“敲”,什么都不“敲”就是语法错误。也不能多“敲”,因为一个单引号内只能放一个字符,“敲”多个空格就是多个字符了。

数组b就是最后没有手动添加 '\0' 的例子。程序是希望数组 b 输出“i miss you”,但输出结果是“i miss you烫i love you”。原因就是系统没有在最后添加'\0'。

虽然程序中对数组 b 的长度进行了限制,即长度为 10,但是由于内存单元是连续的,对于字符串,系统只要没有遇到 '\0',就会认为该字符串还没有结束,就会一直往后找,直到遇到 '\0' 为止。被找过的内存单元都会输出,从而超出定义的 10 字节。

数组 c 是定义时初始化。定义时初始化可以整体赋值。整体赋值有一个明显的优点——方便。定义时初始化可以不用指定数组的长度,而先定义后初始化则必须要指定数组的长度,如数组 a 和数组 b。不用指定数组长度有一个好处:不用人为确定需要多少字节的内存空间,系统会根据初始化的内容自动分配数量正好的内存空间。而且对于数组 c 的写法系统会自动在最后添加结束标志符 '\0',不需要人为添加。

数组 d 也是定义时初始化,但它既属于整体赋值,也属于一个一个赋值。说它是整体赋值是因为不用写 d[0]、d[1]…而说它是一个一个赋值是因为它把整个句子分成了一个一个的字符。还是数组 c 的写法比较方便,而且对于数组d的写法系统也不会自动在最后添加结束标志符 '\0',必须人为添加。如果忘记添加就会出现与数组 b 同样的错误。从数组 e 的输出结果可以看出这一点。

数组 f 是存储汉字,汉字不能像数组 a 或数组 d 那样分开一个一个赋值。因为一个汉字占 2 字节,若分开赋值,由于一个单引号内只能放一个字符,即一字节,所以将占 2 字节的汉字放进去当然就出错了。因此如果用字符数组存储汉字的话必须整体赋值,即要么定义时初始化,要么调用 strcpy 函数。

数组 g 初始化为一对双引号,表示该字符数组中 10 个元素的内容都为 '\0'。下面写一个程序验证一下:

# include <stdio.h>
int main(void)
{
char str[] = "";
str[] = 'a';
printf("str = %s\n", str);
return ;
}

输出结果是:
str =

程序中定义了一个长度为 3 的字符数组,然后给第三个元素赋值为 'a',然后将整个字符数组输出。但是输出结果什么都没有,原因就是其直接初始化为一对双引号,此时字符数组中所有元素都是 '\0'。所以虽然第三个元素为 'a',但因为第一个元素为 '\0',而 '\0' 是字符串的结束标志符,所以无法输出。

需要注意的是,使用此种初始化方式时一定要指定数组的长度,否则默认数组长度为 1。

总结,字符数组与前面讲的数值数组有一个很大的区别,即字符数组可以通过“%s”一次性全部输出,而数值数组只能逐个输出每个元素。

C语言字符数组详解的更多相关文章

  1. 《C语言》—— 数组详解

    书籍使我变成了一个幸福的人,使我的生活变成轻松而舒适的诗.--高尔基 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues. https://github.com/midou-tec ...

  2. c语言贪吃蛇详解3.让蛇动起来

    c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...

  3. Python2.7字符编码详解

    目录 Python2.7字符编码详解 声明 一. 字符编码基础 1.1 抽象字符清单(ACR) 1.2 已编码字符集(CCS) 1.3 字符编码格式(CEF) 1.3.1 ASCII(初创) 1.3. ...

  4. C语言memset函数详解

    C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即“内存”(memory)的意思.该函数的原型为: # ...

  5. 转1:Python字符编码详解

    Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...

  6. C语言中字符串详解

    C语言中字符串详解 字符串时是C语言中非常重要的部分,我们从字符串的性质和字符串的创建.程序中字符串的输入输出和字符串的操作来对字符串进行详细的解析. 什么是字符串? C语言本身没有内置的字符串类型, ...

  7. C语言内存对齐详解(2)

    接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...

  8. c语言贪吃蛇详解-2.画出蛇

    c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...

  9. c语言贪吃蛇详解1.画出地图

    c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...

随机推荐

  1. 一分钟理解sku和spu

    SPU SPU = Standard Product Unit (标准化产品单位) SPU是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合,该集合描述了一个产品的特性.通俗点讲,属性值 ...

  2. 优化 Karatsuba 乘法(老物)

    虽然写好了我自己用的a*启发函数但还是有些不尽人意,如果通过数学分析确定不出问题可以工作了的话应该就会发出来了 // Karatsuba 递归式距离推导 // h(x) = f(x) * g(x):/ ...

  3. 利用bing图片搜索接口开发图片搜索应用程序

    概述:通过bing的图片搜索引擎,开发自己的图片搜索应用程序.bing的图片搜索接口是收费的,但是初次注册使用,key可以免费试用30天 程序运行效果如下 一,代码如下 static SearchRe ...

  4. flutter-常见的基础组件(一)

    flutter 1.Text 文本组件 Text( 'czklove', //文本上的文字 style: TextStyle( // style 代表对文字的描述 fontSize: 18, //文字 ...

  5. 日语能力考试N2级核心词汇必备—接续词

    日语能力考试N2级核心词汇必备—接续词 顺接 だから 因为......所以......(下文可用命令,意志劝诱等)その結果  其结果(口语,书面语都行,但是比较生硬)したがって  从而,因而(书面语, ...

  6. uni-app导航栏配置

    uni-app写app的内容会与沉浸栏重合在一起,写好好多,都是有点问题的,这次终于找到解决的方法了,与大家分享一下 最简单的解决方式就是配置mainfest.json来关闭沉浸式.即通过打开应用的m ...

  7. xcode中进行git代码管理

    http://www.cocoachina.com/ios/20140524/8536.html

  8. HB-打包

    一.文件打包 1.上传文件到根目录下 2.修更改启动文件 3.更改启动图标 四.启动图 https://www.yasuotu.com/size 480*762 720*1242 1080*1882

  9. Qualcomm_Mobile_OpenCL.pdf 翻译-6-工作组尺寸的性能优化

    对于许多kernels来说,工作组大小的调整会是一种简单有效的方法.这章将会介绍基于工作组大小的基础知识,比如如何获取工作组大小,为什么工作组大小非常重要,同时也会讨论关于最优工作组大小的选择和调整的 ...

  10. php set_magic_quotes_runtime() 函数过时解决方法

    PHP5.3中 bool set_magic_quotes_runtime ( bool $new_setting )函数过时.把函数: set_magic_quotes_runtime($newse ...