字符数组与字符串——C语言描述

字符数组与字符串——C语言描述

1 字符数组

​ 字符数组用关键字char定义的。内存结构为顺序存储,如下图1.1所示

char ch1[] = {'w', 'e'};

在这里插入图片描述

图1.1 字符数组的内存结构
#include <stdio.h>

/*
目的:
1. 测试字符数组
*/
int main() {
	char ch1[2] = {'w', 'e'};
	int i = 0;

	for (i = 0; i < sizeof(ch1); ++i) {
		printf("ch1[%d] = %c\n", i, ch1[i]);
	}

	getchar();
	return 0;
}

结果:

ch1[0] = w
ch1[1] = e

1.2 ASCII码表

参考链接:

https://blog.csdn.net/xujidong1576324301/article/details/88342192?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164527731916780264046399%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164527731916780264046399&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-88342192.first_rank_v2_pc_rank_v29&utm_term=c%E8%AF%AD%E8%A8%80ascii%E7%A0%81%E8%A1%A8&spm=1018.2226.3001.4187

​ 一共有128(0 - 127)个ASCII码,其中ASCII控制字符是0 - 31和127,ASCII可显示字符是32 - 126。可显示字符中:空格字符ASCII值为32,数字字符(0 - 9)为48 - 57,大写字母字符(A - Z)是65 - 90(26个),小写字母字符(a - z)是97 - 122(26个),对应的大写字母和小写字母相差32个。

例子:

​ 测试ASCII码表的值。

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

/*
Requirement:
1. test ASCII
*/
int main() {
	char ch1[] = { 'w', 0, 'e', 48, 20, 65, 97};
	int i = 0;

	for (i = 0; i < sizeof(ch1); ++i) {
		printf("ch1[%i] = %c\n", i, ch1[i]);
	}

	getchar();
	return 0;
}

结果:

ch1[0] = w
ch1[1] = ——空字符
ch1[2] = e
ch1[3] = 0
ch1[4] = ——空格
ch1[5] = A
ch1[6] = a

1.3 转义字符

​ 如下图1.2所示,主要是针对特殊功能和特殊字符的实现,如换行(\n),打印或者存储特殊字符,如(‘,“,\)。其中转义字符’\0’就是表示ASCII值0(空字符)
在这里插入图片描述

图1.2 转义字符表

例子:

​ 测试转义字符,一般打印这种转义字符,多加一次下划线 \

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

/*
Requirement:
1.test CharArr
*/
int main() {
	char ch1[] = {'w', 'e', '\\', '\'', '\"', '\;'};
	int i = 0;

	for (i = 0; i < sizeof(ch1); ++i) {
		printf("ch1[%i] = %c\n", i, ch1[i]);
	}

	getchar();
	return 0;
}

结果:

ch1[0] = w
ch1[1] = e
ch1[2] = \
ch1[3] = ’
ch1[4] = "
ch1[5] = ;

1.4 常见问题——字符数组初始化没填满或者越界访问

**(1)**测试字符数组没填充满的定义与越界访问

①初始化的字符个数 < 字符数组定义的个数

​ 其他的成员会以空字符进行填充。访问ch2[2]时,结果是空字符。当访问ch2[4],ch2[5],返回的值是乱码。

char ch2[3] = {'w', 'e'};

②初始化的字符个数 > 字符数组定义的个数

	//char ch3[1] = {'w', 'e'};//直接报错

例子:

​ 测试字符数组没填充满,溢出的定义与访问

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

/*
Requirement:
1.测试没填充满,溢出
*/
int main() {
	char ch1[2] = {'w', 'e'};
	char ch2[3] = {'w', 'e'};
	//char ch3[1] = {'w', 'e'};//定义溢出的直接报错
	int i = 0;

	//测试正常
	printf("测试正常:\n");
	for (i = 0; i < sizeof(ch1); ++i) {
		printf("ch1[%d] = %c\n", i, ch1[i]);
	}

	//测试没填充满
	printf("测试没填充满:\n");
	for (i = 0; i < sizeof(ch2); ++i) {
		printf("ch2[%d] = %c\n", i, ch2[i]);
	}

	//测试越界访问
	printf("测试越界访问:\n");
	printf("ch1[3] = %c\n", ch1[3]);
	printf("ch1[4] = %c\n", ch1[4]);

	getchar();
	return 0;
}

结果:

测试正常:
ch1[0] = w
ch1[1] = e
测试没填充满:
ch2[0] = w
ch2[1] = e
ch2[2] = ——空字符
测试越界访问:
ch2[4] = ? ——乱码
ch2[5] = ? ——乱码

2 字符串

2.1 字符串的描述

​ 字符串是以’\0’为结束符的字符数组。’\0’是一个转义字符,转义成ASCII码值为0,也是空字符的意思。在c语言中,字符串用字符数组的形式来定义。定义的方式有两种:第一种,使用{},需要把’\0’加上;第二种:使用””,编译器会自动在后面补’\0’。字符串的内存结构如图2.1所示。理解建议全转换成内存结构来理解。

char c01[] = {'w', 'e', '\0'};
char c02[] = "we";

在这里插入图片描述

图2.1 字符串内存结构

例子:

​ 测试字符串

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

/*
目的:
字符串
*/
int main() {
	//字符数组方式
	char c01[3] = { 'm', 'e', '\0' };
	//字符串
	char c02[3] = "me";
	int i = 0;

	//打印字符数组
	printf("sizeof(c01) = %d\n", sizeof(c01));
	for (i = 0; i < sizeof(c01); ++i) {
		printf("c01[%d] = %c\n", i, c01[i]);
	}
	printf("c01 = %s\n\n", c01);

	//打印字符串
	printf("sizeof(c02) = %d\n", sizeof(c02));
	for (i = 0; i < sizeof(c02); ++i) {
		printf("c02[%d] = %c\n", i, c02[i]);
	}
	printf("c02 = %s\n", c02);

	getchar();
	return 0;
}

打印结果:

sizeof(c01) = 3
c01[0] = w
c01[1] = e
c01[2] = ——空字符
c01 = we

sizeof(c02) = 3
c02[0] = w
c02[1] = e
c02[2] = ——空字符
c02 = we

1.2 常见问题

(1)测试字符串的打印

​ 打印时使用%s占位符进行打印,由于字符串是以’\0’结尾,打印字符串时,系统会去找’\0’,当识别到’\0’时,会结束打印。

例子:

​ 测试以%s的方式打印字串.

#include <stdio.h>

/*
Requirement:
1.测试以%S的方式打印字串
*/
int main() {
	//'\0'在中间
	char ch1[4] = {'w', 'e', '\0', 'a'};
	char ch2[5] = "we\0a";//用""定义字符串会在后面加'\0'
	int i = 0;
	
	//测试ch1
	printf("测试ch1:\n");
	printf("ch1 = %s\n", ch1);//遇见空字符'\0'就停止
	for (i = 0; i < sizeof(ch1); ++i) {
		printf("ch[%d] = %c\n", i, ch1[i]);
	}

	//测试ch2
	printf("测试ch2:\n");
	printf("ch2 = %s\n", ch2);//遇见空字符'\0'就停止
	for (i = 0; i < sizeof(ch2); ++i) {
		printf("ch2[%d] = %c\n", i, ch2[i]);
	}


	getchar();
	return 0;
}

结果:

测试ch1:
ch1 = we
ch[0] = w
ch[1] = e
ch[2] =
ch[3] = a
测试ch2:
ch2 = we
ch2[0] = w
ch2[1] = e
ch2[2] =
ch2[3] = a
ch2[4] =

(2)测试字符数组没填充满,即初始化的字符个数 < 字符数组定义的个数

#include <stdio.h>

/*
Requirement:
1.测试没填满
*/
int main() {
	char ch3[6] = "wea";//在'a'后面会自动添加'\0'
	int i = 0;

	//测试ch3
	printf("测试ch3:\n");
	printf("ch3 = %s\n", ch3);//遇见空字符'\0'就停止
	for (i = 0; i < sizeof(ch3); ++i) {
		printf("ch3[%d] = %c\n", i, ch3[i]);
	}

	getchar();
	return 0;
}

结果:

测试ch3:
ch3 = wea
ch3[0] = w
ch3[1] = e
ch3[2] = a
ch3[3] =
ch3[4] =
ch3[5] =

1.2 常用的字符串函数

函数功能
strlen(str);返回字符串str1的长度
strcpy(str1, str2);复制字符串str2到字符串str1
strcat(str1, str2);把字符串str2连接到字符串str1的末尾
strcmp(str1, str2);比较字符串的长度。当str1等于str2,返回0,当str1 > str2,返回值 > 0 ,否则 < 0
strchr(str1, ch);返回一个指针,指向字符串第一次出现出现字符ch的位置
strstr(str1, str2);返回一个指针,指向字符串第一次出现出现字符串str2的位置

(1)strlen

​ 返回字符串str1的长度。不包括’\0’;

sizeof函数

​ 存储空间的字节个数,所以计算的时候要按内存空间来理解。

(2)复制:strcpy_s

参考:

https://blog.csdn.net/leowinbow/article/details/82380252?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164897107816781685318527%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164897107816781685318527&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-82380252.142v5pc_search_result_control_group,157v4control&utm_term=strcpy_s&spm=1018.2226.3001.4187

①函数原型:

​ 第二个参数(numberOfElements)是为了保证strSource的缓冲长度

errno_t strcpy_s( char *strDestination,  size_t numberOfElements,  const char *strSource );

例子:

//test strcpy_s
void test08() {
	char str1[6] = "we go";
	char *str = NULL;
	int i = 0;
    
	str = (char *)malloc(sizeof(str1));
	strcpy_s(str, sizeof(str1), str1);

	printf("str = %s\n", str);
	for (i = 0; i < sizeof(str1); ++i) {
		printf("str[%d] = %c\n", i, str[i]);
	}

	free(str);
	str = NULL;
 }

结果:

str = we go

str[0] = w

str[1] = e

str[2] =

str[3] = g

str[4] = o

str[5] =

②溢出情况

​ 目标数组的长度小于源数组的长度,程序会报错。

//test strcpy_s overflow
void test09() {
  char str1[6] = "we go";
  char str2[2];

  strcpy_s(str2, sizeof(str1), str1);

  printf("str = %s\n", str2); 
}

结果:

程序报错

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值