由浅到深认识C语言(4):数组

该文章Github地址:https://github.com/AntonyCheng/c-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识C语言(3):C语言的类型及语句

3.数组

3.1.数组的概念

概念:在程序设计中,为了方便处理数据,把具有相同类型得若干变量按连续空间形式储存起来——称为数组;数组属于构造数据类型,一个数组可以分解为多个数组元素,这些数组元素可以是基本数组类型或者构造类型;

3.2.数组的分类

按照数组元素分类 { 基本数据类型: i n t   a [ 10 ] 结构类型: s t r u c t   s t u   b o y [ 10 ] 按照数组类型分类 { 数值数组: i n t   a [ 10 ] 字符数组: c h a r   s [ 10 ] 指针数组: c h a r   ∗ p [ 10 ] 结构数组 按照数组元素分类\begin{cases} 基本数据类型:int\ a[10]\\ 结构类型:struct\ stu\ boy[10]\end{cases}\\ \\ 按照数组类型分类\begin{cases} 数值数组:int\ a[10] \\字符数组: char\ s[10] \\指针数组: char\ ^*p[10] \\结构数组 \end{cases} 按照数组元素分类{基本数据类型:int a[10]结构类型:struct stu boy[10]按照数组类型分类 数值数组:int a[10]字符数组:char s[10]指针数组:char p[10]结构数组

3.3.一维数组

一维数组的定义

  • 数组的定义

    需求:请定义一个数组,该数组有 10 个元素,元素都为 int 类型;

    定义的过程

    • arr[] --------arr[] 结合是数组;
    • 将确定的元素的个数放入 [] 中;
    • 用元素的类型定义一个普通变量;
    • 然后

    示例如下:

    int arr[10];
    

    再定义一个数组,该数组有 10 个整型元素,元素都为地址类型(指针);

    int *arr[10];
    

    注意:

    • 数组名不能和其他变量名同名;
    • 数组的元素小标是从 0 开始;
    • arr[10] 里的元素是 arr[0]、arr[1]、……、arr[9] ,如果访问 arr[10] ,数组越界;
    • 数组的元素等价于普通变量;
    • 在定义数组的时候,[]里面的值不能是变量;(最新的C标准是可以的)
  • 案例:遍历数组;

    void method() {
    	int arr[10];
    	int i = 0;
    	//遍历数组
    	printf("\n");
    	for (i = 0; i < 10; i++) {
    		printf(" %d ", arr[i]);
    	}
    	printf("\n");
    }
    int main(int argc, char* argv[]) {
    	method();
    	return 0;
    }
    

    打印效果如下:

在这里插入图片描述

初始化

初始化:定义的时候,给变量或者数组元素赋值的动作,就叫做初始化;

示例如下:

int num = 100;//这是初始化
num = 100;//这是赋值,不是初始化
  • 全部初始化:

    int arr[5] = {1,2,3,4,5};
    

    全部初始化时,元素的个数可以省略: arr[5] --> arr[] (尽量少用)

    int arr[] = {1,2,3,4,5};
    
  • 部分初始化:

    int arr[10] = {1,2,3};
    

    未被初始化的部分自动补 0 ;

    示例如下:

    void method() {
    	int arr[10] = { 1,2,3 };
    	int i = 0;
    	//遍历数组
    	printf("\n");
    	for (i = 0; i < 10; i++) {
    		printf(" %d ", arr[i]);
    	}
    	printf("\n");
    }
    int main(int argc, char* argv[]) {
    	method();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    应用:我们可以用部分初始化去重置整个数组;

     int arr[5] = {0};
    

    案例如下:

    void method() {
    	int arr[10] = {0};
    	int i = 0;
    	//遍历数组
    	printf("\n");
    	for (i = 0; i < 10; i++) {
    		printf(" %d ", arr[i]);
    	}
    	printf("\n");
    }
    int main(int argc, char* argv[]) {
    	method();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 扩展(了解):

    如果我们想规定第三位和第五位的数字为 5 和 3 ,其他位为 0 ,示例如下:

    void method() {
    	int arr[10] = { [2] = 5,[4] = 3 };
    	int i = 0;
    	//遍历数组
    	printf("\n");
    	for (i = 0; i < 10; i++) {
    		printf(" %d ", arr[i]);
    	}
    	printf("\n");
    }
    int main(int argc, char* argv[]) {
    	method();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数组的空间大小

引入示例:

void method() {
	int arr[10] = {1,2,3,4,5,6,7,8,9,0};
	printf(" 数组的总大小 = %d\n", sizeof(arr));
    //这里测量的是 arr ,即整个数组
    //如果我们要测数组中的单独元素的大小
    //应该用 arr[0] ~ arr[9] 其中的一个
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看出一个数组的内存总大小等于数组内的所有元素内存大小之和;

这样我们也可以推算出整个数组的元素个数:

int n = sizeof(arr)/sizeof(arr[0]);

我们可以利用上例便于代码的移植性:

首先我们先定义一个数组:

void method() {
	int num[5] = {11,22,33,44,55};
	int i = 0;
	printf("我们对此遍历一下:\n");
	for (i = 0; i < 5; i++) {
		printf(" %d ", num[i]);
	}
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

显然该数组打印结果为 :11 22 33 44 55

当我们要改变数组中的元素数量再遍历时:

void method() {
	int num[10] = {11,22,33,44,55,66,77,88,99,100};
	int i = 0;
	printf("我们对此遍历一下:\n");
	for (i = 0; i < 10; i++) {
		printf(" %d ", num[i]);
	}
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

这样的修改方法会修改两处,一是修改数组的内容,二是修改for循环,所以我们可以优化:

void method() {
	//首先我们先定义一个数组
	int num[10] = {11,22,33,44,55,66,77,88,99,100};
	int i = 0;
	int n = sizeof(num) / sizeof(num[0]);
	printf("我们对此遍历一下:\n");
	for (i = 0; i < n; i++) {
		printf(" %d ", num[i]);
	}
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

可以看出我们可以先将元素个数算出来,然后将该数替换掉原来的循环条件,这样只需要修改数组了;

数组元素的操作

void method() {
	int arr[5] = { 1,2,3,4,5 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	
	//给数组元素赋值
	arr[0] = 100;
	
	//num++;
	arr[1]++;//arr[1] = arr[1] + 1;

	//scanf("%d",&num);
	printf("改变第三位的值:");
	scanf_s("%d", &arr[2]);

	for (i = 0; i < n; i++) {
		printf(" %d ", arr[i]);
	}
	printf("\n");
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

案例:定义一个数组,一共五个 int 元素,获取键盘输入;

void method() {
	int arr[5] = { 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < n; i++) {
		printf("一共有 5 位数字,请修改第 %d 位数字:", i+1);
		scanf_s("%d", &arr[i]);
	}
	printf("修改完毕!");
    //最后输出也可以用循环实现
	printf("修改后的结果是:\n %d %d %d %d %d",arr[0], arr[1], arr[2], arr[3], arr[4]); 
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例:定义数组,一共五个int元素,获取键盘输入,并求出最大值,最小值和平均值;

傻乎乎算法:

void method() {
	int arr[5] = { 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < n; i++) {
		printf("一共有 5 位数字,请修改第 %d 位数字:", i+1);
		scanf_s("%d", &arr[i]);
	}
	printf("修改完毕!");
	printf("修改后的结果是:\n %d %d %d %d %d",arr[0], arr[1], arr[2], arr[3], arr[4]);
	int max = 0;
	if (arr[0] >= arr[1] & arr[0] >= arr[2] & arr[0] >= arr[3] & arr[0] >= arr[4]) {
		max = arr[0];
	}
	if (arr[1] >= arr[0] & arr[1] >= arr[2] & arr[1] >= arr[3] & arr[1] >= arr[4]) {
		max = arr[1];
	}
	if (arr[2] >= arr[0] & arr[2] >= arr[1] & arr[2] >= arr[3] & arr[2] >= arr[4]) {
		max = arr[2];
	}
	if (arr[3] >= arr[1] & arr[3] >= arr[2] & arr[3] >= arr[0] & arr[3] >= arr[4]) {
		max = arr[3];
	}
	if (arr[4] >= arr[1] & arr[4] >= arr[2] & arr[4] >= arr[3] & arr[4] >= arr[0]) {
		max = arr[4];
	}
	int min = 0;
	if (arr[0] <= arr[1] & arr[0] <= arr[2] & arr[0] <= arr[3] & arr[0] <= arr[4]) {
		min = arr[0];
	}
	if (arr[1] <= arr[0] & arr[1] <= arr[2] & arr[1] <= arr[3] & arr[1] <= arr[4]) {
		min = arr[1];
	}
	if (arr[2] <= arr[0] & arr[2] <= arr[1] & arr[2] <= arr[3] & arr[2] <= arr[4]) {
		min = arr[2];
	}
	if (arr[3] <= arr[1] & arr[3] <= arr[2] & arr[3] <= arr[0] & arr[3] <= arr[4]) {
		min = arr[3];
	}
	if (arr[4] <= arr[1] & arr[4] <= arr[2] & arr[4] <= arr[3] & arr[4] <= arr[0]) {
		min = arr[4];
	}
	int average = (arr[0] + arr[1] + arr[2] + arr[3] + arr[4]) / n;
	printf("你输入的数字中最大值是 %d ,最小值是 %d ,平均值是 %d\n", max,min,average);
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

优化上述算法:

void method() {
	int arr[5] = { 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++) {
		printf("一共有 5 位数字,请修改第 %d 位数字:", i+1);
		scanf_s("%d", &arr[i]);
	}
	printf("修改完毕!");
	printf("修改后的结果是:\n %d %d %d %d %d\n",arr[0], arr[1], arr[2], arr[3], arr[4]);
	int max = 0;
	int count;
	for (i = 0; i < n; i++) {
		count = 0;
		for (j = 0; j < n; j++) {
			if (arr[i] >= arr[j]) {
				count++;
			}
		}
		if (count == 5) {
			max = arr[i];
		}
	}
	int min = 0;
	for (i = 0; i < n; i++) {
		count = 0;
		for (j = 0; j < n; j++) {
			if (arr[i] <= arr[j]) {
				count++;
			}
		}
		if (count == 5) {
			min = arr[i];
		}
	}
	int sigle = 0;
	int average = 0;
	for (i = 0; i < n; i++) {
		sigle += arr[i];
	}
	average = sigle / n;
	printf("你输入的数字中最大值是 %d ,最小值是 %d ,平均值是 %d\n",max,min,average);
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

”假设”算法:

void method() {
	int arr[5] = { 0 };
	int n = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < 5; i++) {
		printf("请你输入第%d个数:", (i + 1));
		scanf_s("%d", &arr[i]);
	}
	int compare = 0;  //此时假设 compare 是最大的
	for (i = 0; i < 5; i++) {
		if (compare < arr[i]) {
			compare = arr[i];
		}
	}
	printf("最大值为%d", compare);
	for (i = 0; i < 5; i++) {
		if (compare > arr[i]) {
			compare = arr[i];
		}
	}
	printf("最小值为%d", compare);
}
int main(int argc, char* argv[]) {
	method();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

冒泡排序算法:

#include<stdio.h>
void test() {
	int arr[10];
	int n = sizeof(arr) / sizeof(arr[0]);
	printf("请输入十个数:");
	for (int i = 0; i < n; i++) {
		scanf_s("%d", &arr[i]);
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (arr[i] <= arr[j]) {
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
			else {
				continue;
			}
		}
	}
	printf("你的排序结果为:");
	for (int i = 0; i < n; i++) {
		printf("%d ", arr[i]);
	}
}

int main(int argc, char* argv[]) {
	test();
	return;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.4.二维数组

C语言允许构造多维数组,多维数组元素有多个下标,以标识它在数组中的位置,所以也成为多下标变量;

多维数组可由二维数组类推而得到;

二维数组的定义

例如下:

int arr[3][4];
//第一个[]里面的值表示行数,第二个[]里面表示列数;
//arr数组有3行4列;
//3行:0~2行 , 4列:0~3列;

二维数组的遍历

示例如下:

void bingo() {
	//二维数组的初始化
	int arr[3][4] = { 0 };
	//遍历第 0 行
	printf("遍历第 0 行:\n");
	int k = 0;
	for (k = 0; k < 4; k++) {
		printf(" %d ", arr[0][k]);
	}
	printf("\n");
	printf("\n");
	//遍历第 0 列
	printf("遍历第 0 列:\n");
	int l = 0;
	for (l = 0; l < 3; l++) {
		printf(" %d \n", arr[l][0]);
	}
	printf("\n");
	//遍历所有元素
	printf("遍历所有元素:\n");
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf(" %d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main(int argc, char* argv[]) {
	bingo();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二维数组的初始化

  • 分段初始化(用 {} 明确地表示一行):

    int arr[3][4] ={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    

    嵌入代码:

    void bingo() {
    	//分段初始化
    	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
    	//遍历第 0 行
    	printf("遍历第 0 行:\n");
    	int k = 0;
    	for (k = 0; k < 4; k++) {
    		printf(" %d ", arr[0][k]);
    	}
    	printf("\n");
    	printf("\n");
    	//遍历第 0 行
    	printf("遍历第 0 列:\n");
    	int l = 0;
    	for (l = 0; l < 3; l++) {
    		printf(" %d \n", arr[l][0]);
    	}
    	printf("\n");
    	//遍历所有元素
    	printf("遍历所有元素:\n");
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < 3; i++) {
    		for (j = 0; j < 4; j++) {
    			printf(" %2d ", arr[i][j]);
    		}
    		printf("\n");
    	}
    }
    int main(int argc, char* argv[]) {
    	bingo();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 连续初始化(一行一行的依次放置):

    int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
    

    嵌入代码:

    void bingo() {
    	//分段初始化
    	int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
    	//遍历第 0 行
    	printf("遍历第 0 行:\n");
    	int k = 0;
    	for (k = 0; k < 4; k++) {
    		printf(" %d ", arr[0][k]);
    	}
    	printf("\n");
    	printf("\n");
    	//遍历第 0 行
    	printf("遍历第 0 列:\n");
    	int l = 0;
    	for (l = 0; l < 3; l++) {
    		printf(" %d \n", arr[l][0]);
    	}
    	printf("\n");
    	//遍历所有元素
    	printf("遍历所有元素:\n");
    	int i = 0;
    	int j = 0;
    	for (i = 0; i < 3; i++) {
    		for (j = 0; j < 4; j++) {
    			printf(" %2d ", arr[i][j]);
    		}
    		printf("\n");
    	}
    }
    int main(int argc, char* argv[]) {
    	bingo();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 案例题目:

    void bingo() {
    	int arr1[3][4] = { {1,2} , {3} , {4,5} };
    	int arr2[3][4] = { 1,2,3,4,5 };
    	printf("%d\n", arr1[1][2] + arr2[1][2]);
    }
    int main(int argc, char* argv[]) {
    	bingo();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 案例:定义一个 3 行 4 列的二维数组,获取键盘输入,并求出每一行和每一列的平均值;

    void bingo() {
    	int arr[3][4] = { 0 };
    	int i = 0;
    	int j = 0;
    	int average1 = 0;
    	int average2 = 0;
    	int average3 = 0;
    	for (i = 0; i < 3; i++) {
    		printf("请输入第 %d 行:\n",i+1);
    		for (j = 0; j < 4; j++) {
    			printf("请输入第 %d 行第 %d 列数字:",i+1,j+1);
    			scanf_s("%d", &arr[i][j]);
    		}
    	}
    	printf("\n该数组为:\n");
    	for (i = 0; i < 3; i++) {
    		for (j = 0; j < 4; j++) {
    			printf("%2d ", arr[i][j]);
    		}
    		printf("\n");
    	}
    	for (i = 0; i < 3; i++) {
    		if (i == 0) {
    			average1 = (arr[i][0] + arr[i][1] + arr[i][2] + arr[i][3]) / 4;
    		}
    		if (i == 1) {
    			average2 = (arr[i][0] + arr[i][1] + arr[i][2] + arr[i][3]) / 4;
    		}
    		if (i == 2) {
    			average3 = (arr[i][0] + arr[i][1] + arr[i][2] + arr[i][3]) / 4;
    		}
    	}
    	printf("第一行的平均值是 %.2f\n第二行的平均值是 %.2f\n第三行的平均值是 %.2f\n", (float)average1, (float)average2, (float)average3);
    }
    int main(int argc, char* argv[]) {
    	bingo();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.5.字符数组

一维字符数组

字符数组:本质是数组,只是数组的每个元素是字符;

char arr[5] = {'h','e','l','l','o'};
//arr[0] == 'h'的 ASCII 值

字符数组的初始化

//逐个字符的初始化
char arr[5] = {'h','e','l','l','o'};
//字符串形式的初始化
char arr[5] = "hello";

上述俩种初始化的区别:

  • 空间大小

    int chars() {
    	char str1[] = { 'h','e','l','l','o' };//逐个字符的初始化
    	char str2[] = "hello";//字符串形式初始化,字符串后面会添加"\0";
    	//空间大小比较
    	printf("逐个字符初始化大小:%d\n字符串初始化的大小:%d\n", sizeof(str1), sizeof(str2));
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • %s 输出的内容

    int chars() {
    	char str1[] = { 'h','e','l','l','o' };//逐个字符的初始化
    	char str2[] = "hello";//字符串形式初始化
    	//空间大小比较
    	printf("sizeof(str1):%s\n", str1);
    	printf("sizeof(str2_:%s\n", str2);
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    我们能够看出这里出现了乱码,原因是 %s ,因为需要遇到 \0 才能结束,所以出现了乱码;

字符数组的遍历

//逐个字符的遍历
int chars() {
	int i = 0;
	char arr[5] = "hello";
	int n = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < n; i++) {
		printf("%c", arr[i]);
	}
}
//字符数组可以整体遍历
int chars() {
	char arr[5] = "hello";
	printf("%s\n", arr);//这样整体遍历,遇到 “\n” 结束;
}

注意:一维数组名代表的是数组第 0 个元素的地址;

解释代码如下:

int chars() {
	char arr[5] = "hello";
	//%p 是十六进制输出地址;
	//printf中的 & 是取地址输出;
	//scanf中的 & 是取地址写入;
	printf("第零个元素的地址是:%p\n", &arr[0]);
	printf("数组地址是:%p\n", arr);
}
int main(int argc, char* argv[]) {
	chars();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

字符数组获取键盘输入:

  • 定义一个字符数组,有足够大的空间,不够大的话容易溢出,污染内存:

    int chars() {
    	char buf[1280] = "" ;
    	printf("请输入一个字符串:");
    	scanf_s("%s", buf, 80);
    	// 80 是 VS 安全输入中的必须的,表示最大输入字符数;
    	//所以定义的时候开辟空间应大于该字符数;
    	printf("str = %s\n", buf);
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    从上例可以看出 scanf_s%s 一起作用的时候是不能获取带空格的字符;

    所以我们要运用到 gets 函数:

    int chars() {
    	char buf[1280] = "" ;
    	printf("请输入一个字符串:");
    	gets(buf);
    	printf("str = %s\n", buf);
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    比较代码可以看出 gets 获取键盘输入的时候不会管 buf 的大小,容易造成内存污染;

    所以我们通常使用 fgets 函数,既可以带空格的字符串,也可以保证 buf 的不越界:

    #include<stdio.h>
    char *fgets(char *s,int size,FILE *stream);
    // s 表示存放字符串的空间地址
    //size表示能够提取字符串中的最大长度 size-1 ;这里的减一是因为获取的字符串中要包含一个 \0
    //stream表示标准输入设备,该参数一般是 stdin 标准输入
    

    示例如下:

    int chars() {
    	char buf[10] = "" ; 
    	printf("请输入一个字符串:");
    	fgets(buf,sizeof(buf),stdin);
    	printf("str = %s\n", buf);
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 案例:字符串的大小写转换;

    先引入字符的大小写转换

    int chars() {
    	//字母的ASCII值
    	//'a' 97  'b'98  ···  'z'122
    	//'A' 65  'B'66  ···  'Z'90
    	char ch = 'a';
    	//我们要将它从小写变为大写
    	ch = ch - 32;//ch = ch -('a' - 'A')
    	printf("ch = %c\n", ch);
    	//我们再将它从大写变为小写
    	ch = ch + 32;
    	printf("ch = %c\n", ch);
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    再看看字符串的转换:

    键盘获取一个字符串,将大写变小写,小写变大写,其他符号不变

    int chars() {
    	char str[100] = "";
    	int i = 0;
    	printf("请输入一个包含大小写且长度不超过100的英文字符串:");
    	fgets(str, sizeof(str), stdin);
    	for (i = 0; i < 100; i++) {
    		if (str[i] >= 'a' && str[i] <= 'z') {
    			printf("%c", str[i]-('a' - 'A'));
    		}
            //空格的ASCII值为 32
    		if (str[i] == 32) {
    			printf(" ");
    		}
    		if (str[i] >= 'A' && str[i] <= 'Z') {
    			printf("%c", str[i] + ('a' - 'A'));
    		}
    	}
    	printf("\n");
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二维字符数组

二维字符数组是用来存放多个字符串的,每个字符串占一行;

char str[2][16] = {"wuchengcheng","chenruying"};
//不管是数值还是字符的二维数组,在初始化的时候是可以省略行标的:
char str[][16] = {"wuchengcheng","chenruying"};
//遍历行如下:
str[0] == "wuchengcheng";
str[1] == "chenruying";

示例如下:

int chars() {
	char str[3][16] = { "hehe","haha","heihei" };
	//输出的是字符串,仅仅使用行标
	printf("%s\n", str[0]);
	printf("%s\n", str[1]);
	printf("%s\n", str[2]);
	//输出字符串中的某个字符,必须行标、列标一起使用
	printf("%c\n", str[0][3]);
	printf("%c\n", str[1][3]);
	printf("%c\n", str[2][5]);
}
int main(int argc, char* argv[]) {
	chars();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二维字符数组获取键盘输入

应用场景:当键盘需要输入多个独立的字符串,用户必须单独存储好;

输入的字符串个数决定了二维字符数组的行数,输入的字符串最大长度决定了二位字符数组的列数;

int chars() {
	char buf[][16] = {"","","",""};
	//char buf[4][16] = {""};
	int i = 0;
	for (i = 0; i < 4; i++) {
		printf("输入第 %d 个数:", i + 1);//因为 %s 能够遇到 \0 自动结束,所以可以省略这里,然后下面键入时用空格隔开
		scanf_s("%s", buf[i],16);//这里也可以是首元素地址:scanf_s("%s",&buf[i][0],16);
	}
	for (i = 0; i < 4; i++) {
		printf("buf[%d] = %s\n", i, buf[i]);
	}
}
int main(int argc, char* argv[]) {
	chars();
	return 0;
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

案例:

  • 键盘输入 10 个int数值,对其从小到大排序;

    int chars() {
    	int arr[10] = { 0 };
    	int i = 0;
    	int j = 0;
    	int count = 0;
    	for (i = 0; i < 10; i++) {
    		printf("请输入第 %d 个数:",i+1);
    		scanf_s("%d", &arr[i]);
    	}
    	for (i = 0; i < 10; i++){
    		for (j = i; j < 10; j++){
    			if (arr[i] <= arr[j + 1]){
    				count = arr[i];
    				arr[i] = arr[j + 1];
    				arr[j + 1] = count;
    			}
    		}
    	}
    	printf("\n排序之后得:\n");
    	for (i = 9; i >= 0; i--) {
    		printf("%d ", arr[i]);
    	}
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 键盘输入一个字符串 "abcdef" 进行前后的颠倒 ----> "fedcba"

    int chars() {
    	char str[100] = { " " };
    	int i = 0;
    	printf("请输入一个字符串:");
    	scanf_s("%s", str, 100);
    	for (i = 99; i >= 0; i--) {
    		if ((int)str[i] == (-2)) {
    			continue;
    		}
    		printf("%c", str[i]);
    	}
    }
    int main(int argc, char* argv[]) {
    	chars();
    	return 0;
    }
    

    打印效果如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一章:由浅到深认识C语言(5):函数

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值