C语言,字符数组与字符串

字符数组基本介绍

用来存放字符的数组称为字符数组, 看几个案例

1)char a[10]; //一维字符数组, 长度为 10
2)char b[5][10]; //二维字符数组, 后面我们详细介绍二维数组
3)char c[20]={‘c’, ’ ', ‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’,‘m’}; // 给部分数组元素赋值

字符数组实际上是一系列字符的集合,也就是字符串(String)。在 C 语言中,没有专门的字符串变量,没有 string 类型,通常就用一个字符数组来存放一个字符串。

字符串注意事项

1)在 C 语言中,字符串实际上是使用 null 字符 (’\0’) 终止的一维字符数组。因此,一个以 null 结尾的字符串, 包含了组成字符串的字符。
2)’\0’是 ASCII 码表中的第 0 个字符,用 NUL 表示,称为空字符。该字符既不能显示,也不是控制字符,输出该 字符不会有任何效果,它在 C 语言中仅作为字符串的结束标志。
3)字符数组(字符串)在内存中的布局分析 [案例]

在这里插入图片描述
4)思考 char str[3] = {‘a’,‘b’,‘c’} 输出什么? 为什么?
输出abc

结论:如果在给某个字符数组赋值时,
(1)赋给的元素的个数小于该数组的长度,则会自动在后面加 ‘\0’, 表示 字符串结束,
(2)赋给的元素的个数等于该数组的长度,则不会自动添加 ‘\0’
char str2[] = {‘t’,‘m’,‘o’} 输出什么? 输出的是 tmo 乱码

5)案例演示

#include <stdio.h> 
void main() { 
	//c 是一个一维字符数组,给部分元素赋值 
	char c[7]={'t','o','m'}; 
	char str[4] = {'a','b','c'}; 
	char str2[] = {'j','a','c','k'}; // 这个后面系统也不会自动添加 '\0' 
	
	char str3[] = {'t','m','o'};
	//输出 c , 系统会这样处理 
	//1. 从第一个字符开始输出,直到遇到 \0 , 表示该字符串结束 
	printf("\nc=%s", c); 
	printf("\nstr=%s", str); // abc? 
	printf("\nstr2=%s", str2); // jack 乱码 
	printf("\nstr3=%s", str3); // 
	
}

字符串的访问和遍历

因为字符串的本质就是字符数组,因此可以按照数组的方式遍历和访问某个元素即可, 案例如下

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 

void main() { 
	char greeting[] = "Hello"; 
	//如果将char greeting[] 改成 char* greeting 对下列式子无任何变化
	int i; 
	//strlen 获取字符数组长度 
	int len = strlen(greeting); // len = 5 
	
	printf("\ngreeting=%s", greeting); 
	printf("\nlen=%d", len); //5 
	
	printf("\n 字符串第 3 个字符是=%c", greeting[2]); //l 
	
	printf("\n"); 
	for(i = 0; i < len; i++) { //遍历 
		printf("%c ", greeting[i]); //H e l l o 
	}
	system("pause"); 
}

对应的内存分析图在这里插入图片描述

字符串的表示形式

用字符数组存放一个字符串: 用字符数组存放一个字符串,

1 )char str[]=“hello tom”;
2)char str2[] = {‘h’, ‘e’};

用字符指针指向一个字符串

比如:char* pStr=" hello tom";

1)C 语言对字符串常量" hello tom"是按字符数组处理的,在内存中开辟了一个字符数组用来存放字符串常量,程 序在定义字符串指针变量 str 时只是把字符串首地址(即存放字符串的字符数组的首地址)赋给 pStr
2)printf("%s\n",str); 可以输出 str 指向的字符串
3)对应的内存布局图(!!)

在这里插入图片描述

使用字符指针变量和字符数组两种方法表示字符串的讨论

1)字符数组由若干个元素组成,每个元素放一个字符;而字符指针变量中存放的是地址(字符串/字符数组的首地址),绝不是将字符串放到字符指针变量中(是字符串首地址)
2)对字符数组只能对各个元素赋值,不能用以下方法对字符数组赋值

char str[14]; 
str=" hello tom"; //错误  str是常量
str[0] = 'i'; //ok

3)对字符指针变量,采用下面方法赋值, 是可以的

char* a="yes"; 
a=" hello tom";

a本身的地址不会发生变化,a指向的地址会发生变化

a本身的地址 -> &a ,a 指向的地址 a
printf(“a本身的地址为 %p,a指向的地址为 %p”, &a,a);

4)分析上面的结论

在这里插入图片描述
5) 如果定义了一个字符数组,那么它有确定的内存地址(即字符数组名是一个常量);而定义一个字符指针变量时, 它并未指向某个确定的字符数据,并且可以多次赋值

字符串相关函数

常用字符串函数一览

序号函数&目的
1strcpy(s1,s2);复制字符串s2到字符串s1
2strcat(s1,s2); 连接字符串s2到字符串s1的末尾
3strlen(s1);返回字符串s1的长度
4strcmp(s1,s2);如果s1,s2相同,则返回0,如果s1 < s2 则小于 0 如果s1 > s2 则大于0
5strchr(s1,ch);返回一个指针,指向字符串s1中字符ch的第一次出现的位置
6strstr(s1,s2);返回一个指针,指向字符串s1中的字符串s2第一次出现的位置

字符串函数应用案例

#include <stdio.h> 
#include <string.h> 

void main() { 
	char str1[12] = "Hello"; 
	char str2[12] = "World"; 
	char str3[12]; 
	
	int len ; 
	
	// 复制 str1 到 str3  
	
	strcpy(str3, str1); // str3 内容 "Hello" 
	printf("strcpy( str3, str1) : %s\n", str3 ); //"Hello" 
	
	// 连接 str1 和 str2 
	strcat( str1, str2); 
	printf("strcat( str1, str2): %s\n", str1 ); //"HelloWorld"
 	// 连接后,str1 的总长度
	 
	len = strlen(str1);// 
	printf("strlen(str1) : %d\n", len );//10 
	
}

在这里插入图片描述

字符串(字符数组)使用注意事项和细节

1) 程序中往往依靠检测 ‘\0’ 的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。因此,字 符串长度不会统计 ‘\0’, 字符数组长度会统计 [案例]
2) 在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度, 否则,在输出字符数组 时可能出现未知字符.
3)系统对字符串常量也自动加一个’\0’作为结束符。例如"C Program”共有 9 个字符,但在内存中占 10 个字节, 最后一个字节’\0’是系统自动加上的。(通过 sizeof()函数可验证)
4)定义字符数组时,如果 给的字符个数 比 数组的长度小,则系统会默认将剩余的元素空间,全部设置为 ‘\0’, 比 如 char str[6] = “ab” , str 内存布局就是 [a][b][\0][\0][\0][\0]
5)字符数组定义和初始化的方式比较多,比如

#include <stdio.h> 

void main() { 
	char str1[ ]={"I am happy"}; // 默认后面加 '\0' 
	char str2[ ]="I am happy"; // 省略{}号 ,默认后面加 '\0'
	char str3[ ]={'I',' ','a','m',' ','h','a','p','p','y'}; // 字符数组后面不会加 '\0', 可能有乱码 
	char str4[5]={'C','h','i','n','a'}; //字符数组后面不会加 '\0', 可能有乱码 
	char * pStr = "hello";//ok 
	
	printf("\n str1=%s", str1); 
	printf("\n str2=%s", str2);//ok 
	printf("\n str3=%s", str3);//乱码 
	printf("\n str4=%s", str4);//乱码
}

字符串(字符数组)课堂练习

char str[ ]; 
str="I am happy"; 

题 1 错误,因为 str 是常量

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值