从零开始,探索C语言中的字符串

字符串

    • [1. 前言](#1. 前言)
    • [2. 预备知识](#2. 预备知识)
      • [2.1 字符](#2.1 字符)
      • [2.2 字符数组](#2.2 字符数组)
    • [3. 什么是字符串](#3. 什么是字符串)
    • 4. '\0'
      • [4.1 '\0'是什么](#4.1 '\0'是什么)
      • [4.2 '\0'的作用](#4.2 '\0'的作用)
        • [4.2.1 打印字符串](#4.2.1 打印字符串)
        • [4.2.2 求字符串长度](#4.2.2 求字符串长度)

1. 前言

大家好,我是努力学习游泳的鱼。你已经学会了如何使用变量和常量,也知道了字符的概念。但是你可能还不了解由字符构成的字符串,这篇文章将带你一探究竟。

2. 预备知识

2.1 字符

单引号引起来的一个字符,用来初始化char类型的变量。

c 复制代码
'a'; // 这是一个字符
char ch = 'w'; // 用来初始化char类型的变量

2.2 字符数组

字符数组可以存储很多字符,格式是char+空格+数组名+左方括号(+数组最多存储的字符个数,如果省略就默认取初始化的字符个数)+右方括号+初始化(大括号引起来几个字符,中间用逗号隔开)。

c 复制代码
char ch[3] = { 'a', 'b', 'c' }; // 最多存3个字符,即a,b,c
char ch[] = { 'd', 'e', 'f', 'g' }; // 方括号内省略字符个数,默认为4,因为初始化了4个字符

3. 什么是字符串

用双引号引起来的一串字符叫做字符串。

c 复制代码
"abcdefg"; // 这就是一个字符串

4. '\0'

4.1 '\0'是什么

字符串可以用来初始化字符数组。

c 复制代码
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c' };

arr1和arr2有什么区别呢?

我们发现,arr2就是很正常的存储了a,b,c这3个字符,但是arr1在后面还跟了个'\0'。

这个'\0'究竟是何方神圣?

字符串的结尾都隐藏了一个叫做'\0'的转义字符。

"abc"这个字符串其实是4个字符:'a','b','c','\0',所以说,

字符串的结束标志是'\0'。

4.2 '\0'的作用

4.2.1 打印字符串

我们可以用printf配合%s打印字符串。

c 复制代码
#include <stdio.h>

int main()
{
	printf("%s\n", "abcdef");
	
    return 0;
}

把上面的arr1和arr2打印出来会是怎样的呢?

c 复制代码
#include <stdio.h>

int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a', 'b', 'c' };

	printf("%s\n", arr1);
	printf("%s\n", arr2);

	return 0;
}

输出:
abc
abc烫烫烫烫烫烫烫烫烫烫bc

我们发现,字符串arr1正常打印,但是字符数组arr2打印出来的是个啥玩意呀?

要搞清楚这一点,就要明白arr1和arr2的内存布局,以及'\0'的作用。
arr1是用字符串"abc"初始化的,根据前面说的,字符串的结束标志是\0,字符串的结尾都隐藏了一个\0,arr1数组里相当于存储了'a','b','c','\0'四个字符。

而arr2就不一样了,它只是单纯的用三个字符'a','b','c'来初始化的,里面也只存放着这三个字符,后面没有'\0',内存中后面放了什么,我们无从知晓。

而%s是用来打印字符串的,还是那句话,字符串的结束标志是'\0'。

在打印arr1时,打印了'a','b','c',就遇到了'\0'这个结束标志,停止打印。

反观arr2,打印完'a','b','c',没有遇到'\0',就继续把内存中后面的值打印出来,直到遇到'\0'才停止。可是,我们不知道内存中后面放了啥,换句话说,内存中后面放的都是些随机值,那打印出来的也是随机值,具体表现出来就是abc后面的烫烫烫。

如果我们手动放一个'\0',两个字符数组的内存布局就一样了。

c 复制代码
#include <stdio.h>

int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a', 'b', 'c', '\0' };

	printf("%s\n", arr1);
	printf("%s\n", arr2);

	return 0;
}

输出:
abc
abc

4.2.2 求字符串长度

我们可以用strlen函数求字符串长度。

strlen是C语言提供的库函数,对应的头文件是string.h,使用时只需要把字符串传进去就可以了。

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a', 'b', 'c' };

	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	
	return 0;
}

输出:
3
42

有了前面的知识,就很容易理解这个结果了。
arr1里面存的是'a','b','c','\0',由于有'\0'的存在,可以很清楚的求出字符串的长度是3,也就是'\0'前面的字符的个数。

反观arr2,因为'a','b','c'后面没有'\0',所以无法求出其长度。就这次的运行结果而言,程序在内存中一直往后找呀找呀,从'a'开始一直找了42个字符才在内存中遇到了'\0',于是算出来的结果是42。这个结果是不可预料的,它是个随机值。

如果手动放一个'\0',就能够准确地求出它的长度了。

c 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a', 'b', 'c', '\0' };

	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	
	return 0;
}

输出:
3
3

总结:strlen求的是'\0'前面字符的个数!

相关推荐
http阿拉丁神猫3 小时前
Go语言入门笔记:从基础到开发环境搭建(二)
开发语言·笔记·golang
不会就选b4 小时前
C++补充部分(一)--lambda 表达式
开发语言·c++
Pniubi7 小时前
HashMap的扩容和树化边界
java·开发语言
gCode Teacher 格码致知9 小时前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工9 小时前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留9 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#
ShineWinsu9 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
益莱储中国11 小时前
深度解析:RF 实验室从 5G迈向 6G 的过程中保持技术领先与设备升级的路径
开发语言·php
丰色木夕12 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
benchmark_cc12 小时前
Python 量化系统如何设计统一的数据访问接口:从策略解耦到数据层架构
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash