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

该文章Github地址:https://github.com/AntonyCheng/c-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & 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):函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/467407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

市场复盘总结 20240318

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 36% 最常用…

【LeetCode每日一题】303. 区域和检索 - 数组不可变

文章目录 [303. 区域和检索 - 数组不可变](https://leetcode.cn/problems/range-sum-query-immutable/)思路&#xff1a;前缀和代码&#xff1a; 303. 区域和检索 - 数组不可变 思路&#xff1a;前缀和 1.因为要根据给出的两个索引&#xff0c;来返回索引区间的和 2.创建一个…

选Gitee还是GitHub?

2024年3月18日&#xff0c;周一晚上 我选择GitHub 因为GitHub可以无限创建仓库

电脑装win11(作si版)

装win11经历 前言&#xff1a;因为我的u盘今天到了&#xff0c;迫不及待试试装机 然后在一系列准备好工具后&#xff0c;便是开始拿学校的机房电脑来试试手了~~ 前期准备 下载好win11镜像&#xff08;可以去微软官网下载&#xff09; 下载Rufus工具 https://www.lanzoue.com/…

Qt学习--继承(并以分文件实现)

基类 & 派生类 一个类可以派生自多个类&#xff0c;这意味着&#xff0c;它可以从多个基类继承数据和函数。定义一个派生类&#xff0c;我们使用一个类派生列表来指定基类。类派生列表以一个或多个基类命名。 总结&#xff1a;简单来说&#xff0c;父类有的&#xff0c;子…

【Chapter1】操作系统概述,计算机操作系统教程,第四版,左万利,王英

文章目录 一、操作系统的基本概念1.1操作系统的层次结构1.2操作系统的运行视图1.3操作系统的概念(定义)1.4操作系统的功能和目标1.4.1操作系统的功能和目标——作为系统资源的管理者1.4.2操作系统的功能和目标——向上层提供方便易用的服务1.4.2.1GUI&#xff1a;图形化用户接口…

力扣函数题:查找子字符串

//C语言strstr(str1,str2);判断字符串str2是否是str1的子串&#xff0c;是返回str1字符串从str2第一次出现的位置开始到str1结尾的字符串&#xff0c;否则返回NULLint numOfStrings(char ** patterns, int patternsSize, char * word){int n0;int i0;while(i<patternsSize){…

综合交易模型----可转债三低策略实盘qmt版,提供源代码

链接 综合交易模型----可转债三低策略实盘qmt版&#xff0c;提供源代码 (qq.com) 可转债3低策略是指选择正股市值低、转债余额低、溢价率低的可转债进行投资的策略。 市值低&#xff1a;指的是可转债对应的正股市场价值较小&#xff0c;这通常意味着需要较少的资金就可以对股价…

upload-labs-pass01

1.安装好环境进入关卡&#xff08;记得打开小皮&#xff09; 2.可以看到第一关是要求上传图片&#xff0c;但是同时限制了图片类型&#xff0c;那么如果我们将木马写入图片&#xff0c;但是类型又不在白名单&#xff0c;就要想办法绕过 3.可以看到这里的要求是有check&#xff…

二、python基础

一、关键字&#xff08;保留字&#xff09; 指在python中赋予特定意义的一类单词&#xff0c;不能将关键字作为函数、变量、类、模块的名称 import keyword#利用内存模块keyword print(keyword.kwlist)#输出所有关键 print(len(keyword.kwlist))#利用内置函数len()输出关键字的…

Python--类中作用域

1、在面向对象编程中&#xff0c;主要的变量就是成员变量&#xff08;属性&#xff09;和局部变量 class Cat:# 属性name Noneage None# n1, n2, result为局部变量def cal(self, n1, n2):result n1 n2print(f"result{result}") 2、作用域的分类&#xff1a;属性…

单链表OJ题

单链表OJ题&#xff08;文字解读 图解&#xff09; 1. 移除链表元素2. 反转链表3. 链表的中间结点4. 返回倒数第 k 个节点5. 合并两个有序链表 1. 移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff…

Obsidian使用200+插件与70+种主题分享

主题资源 下载方式一&#xff1a; 网盘下载 密码:a3eu 下载方式二&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fOgP8lY29sYxkUAbTlQQCw 提取码&#xff1a;qhxa 下载解压打开红色框文件夹 上面的是插件&#xff0c;下面的是主题 以下介绍安装主题 打开Obsidi…

【小白笔记:JetsonNano学习(一)SDKManager系统烧录】

参考文章&#xff1a;SDKManager系统烧录 小白烧录文件系统可能遇到的问题 担心博主删除文章&#xff0c;可能就找不到比较详细的教程了&#xff0c;特意记录一下。 Jetson Nano采用四核64位ARM CPU和128核集成NVIDIA GPU&#xff0c;可提供472 GFLOPS的计算性能。它还包括4GB…

Linux信号灯

目录 一、什么是信号量 二、PV操作概念 三、信号灯 四、有名信号灯 五、无名信号灯 一、什么是信号量 线程的信号量与进程间通信中使用的信号量的概念是一样&#xff0c;它是一种特殊的变量&#xff0c;它可以被增加或减少&#xff0c;但对其的关键访问被保证是原子操作。…

搜索二叉树迭代和递归的两种*简单*实现方式

判断搜索二叉树 概念 一棵树所有结点的左节点小于父节点&#xff0c;右节点大于父节点&#xff0c;则为搜索二叉树。 迭代方法 中序遍历二叉树&#xff0c;如果总是升序则是搜索二叉树。如果存在降序&#xff0c;那肯定不是搜索二叉树。 Coding checkTreeOrder()方法 boo…

js判断对象是否有某个属性

前端判断后端接口是否返回某个字段的时候 <script>var obj { name: "John", age: 30 };console.log(obj.hasOwnProperty("name")); // 输出 trueconsole.log(obj.hasOwnProperty("email")); // 输出 falselet obj11 { name: "Joh…

DNF的概念和操作命令

yum是linux系统中基于rpm包管理的一种软件管理工具。 在dnf.conf文件中&#xff0c;我们可以配置某个网络服务器位软件源仓库。配置的方法&#xff0c;就是用vim编辑/etc/dnf/dnf.conf这个文件。

数字化转型导师坚鹏:人工智能在金融机构数字化转型中的应用

人工智能在金融机构数字化转型中的应用 课程背景&#xff1a; 金融机构数字化转型离不开人工智能&#xff0c;在金融机构数字化转型中&#xff0c;人工智能起到至关重要的作用&#xff0c;很多机构存在以下问题&#xff1a; 不清楚人工智能产业对我们有什么影响&#xff1f;…

Netty学习——源码篇2 客户端Bootstrap(一) 备份

1 Channel简介 在Netty中&#xff0c;Channel相当于一个Socket的抽象&#xff0c;它为用户提供了关于Socket状态&#xff08;是连接还是断开&#xff09;以及对Socket的读写等操作。每当Netty建立了一个连接&#xff0c;都创建一个与其对应的Channel实例。 除了TCP&#xff0c;…