C语言中没有字符串类型怎么办?

C语言没有专门的字符串类型,而是通过字符数组来处理字符串。本文介绍了字符数组的定义、初始化、访问元素、修改元素以及使用字符串常量初始化字符数组的方法,强调了数组初始化时添加''的重要性以及避免数组越界的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串与字符数组

  在前面的章节中,我们知道了可以定义char类型的变量来装字符常量。

char c1, c2;
c1 = 'a';
c2 = 'b';

  也打印过类似于"HelloWorld",这样的字符串常量,被括号包括的,就是字符串字面常量了。

printf("%s", "HelloWorld\n");

  那我们很自然的会想到,字符串常量可以用什么类型的变量来装?

  很遗憾,C语言里面没有专门的字符串类型。在C语言中,字符串是被当做字符数组来处理的。

1. 字符数组

  什么是数组呢?

  我们之前都是用 类型+标识符; 来定义单个的变量。

char c1;
char c2, c3;

  现在我们来学习一种,一下子定义多个变量的方式。

  变量 + 标识符 + [变量的个数]

  例如:

char arr[6];

  定义了一个字符数组,数组名为arr,它其中有6个元素,每一个元素都是一个字符类型的变量。

字符数组

2. 数组初始化

  在之前我们学习过变量的初始化。例如,我定义一个整型变量n,并初始化为0。

int n = 0;

  这里看来初始化好像和赋值没什么区别。基础变量的初始化,与赋值几乎语法和效果一致。但是,我们来看看数组的初始化。

char arr[10] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("%s\n", arr);

字符数组初始化

  这里就有些区别了吧,数组的初始化要求=号右边使用花括号。花括号内部为需要初始化的值,并用逗号隔开。我们初始化的是时候,尽量加上’\0’。用于表示字符串的结尾。没有结尾的字符串会造成printf打印过界。

  不如,我们来试试看不加’\0’的情况吧?

字符数组初始化无结尾符

  为什么也是正常的呢?难道’o’后面已经默认是’\0’了吗?我们来检查一下看看,打印一下数组的’o’后面到底是什么?

default0

3. 访问数组的元素

访问数组元素

  访问数组元素的公式:数组名+[序号],注意序号从0开始。

  字符类型事实上就是一种范围很小的整型,它只有一个字节,表示范围为-128到+127。由于它可以刚好装下整个字符到数值的映射表美国信息交换标准代码ASCII(American Standard Code for Information Interchange)的数值。所以,叫做字符类型。

ascii

  表中,H的值为72,e的值为101,和我们上面用%d来打印的值一致。%c表示将数值用字符来打印,%d表示用整型来打印。而char本身事实上就是一个范围很小的整型变量,它内部存储的是数值,不是字符。把数值根据ASCII显示成字符,是printf函数做的功能。

  好了,让我们回到上面的问题。我们定义了10个元素,但是只初始化了6个元素。没有被初始化到的部分,被默认填充了数值0。而数值0在ASCII里面就是NUL,空,也就是我们常说的’\0’。所以,printf已经正常打印完结束了。

0结束打印

  我们还发现,[10],[11]所代表的元素已经超出了数组的范围,所以,它是一个奇怪的值。注意,在正常编程中,千万不要使用超出数组本身范围的变量。这种行为叫做 数组越界,严重的情况可能会导致崩溃。

  这里,我们来人为制造一次越界的情况。我们把数组长度定义为5,那么’o’后面就没有’\0’了,而是一些奇怪的值。而printf打印字符串时,没有’\0’是不会结束的,所以它会一直越界出去。

越界

  果真如此,由于’o’后面没有’\0’,所以数组越界了。为什么printf会停止呢?可能它碰巧遇到了一个’\0’吧,越界后的值是无意义的。

4. 修改数组的元素

  之前我们说过字符串字面常量是不能被修改的,没错,任何常量都不能被修改。但是,字符数组却是可以修改的。

字符数组修改

  上面的代码中,将第一个元素由大写的’H’,修改成了小写的’h’。

5. 注意不要越界

注意越界

  除了不要在初始化的时候定义,访问的时候也请注意不要越界。记住序号是从0开始的,不要访问,赋值超过数组大小的位置。

6. 使用字符串常量初始化字符数组

int main()
{
	char arr[10] = "HelloWorld";
	printf("%s\n", arr);
	return 0;
}

  字符数组初始化除了使用{},还可以直接用字符串字面常量进行初始化。但是仅仅是用于初始化的时候,不能用于赋值。 这也是初始化不同于赋值的一个地方。

int main()
{
	char arr[10] = "HelloWorld";
	printf("%s\n", arr);
	arr = "apple"; //  错误的
	return 0;
}

  在这里,我们肯定也会关心"HelloWorld"有没有带有’\0’结束符,以确认打印时,会不会越界。我们来看一下字符串的内存组成。

helloworld\n

  字符串字面常量是带有’\0’的,否则直接用printf打印"HelloWorld"也会出现越界的问题。所以,这种初始化,我们无需再加’\0’了。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值