如何系统学习C 语言(中)之 数组篇

前言:公号 「编程有料」后台回复 “大礼包” 即可获取近1000本助力你编程之路的电子书

前面了解了c 语言的基础部分,下面在对它进行一个深入的了解吧

数组

1,一维数组

数组是用来干嘛的呢?就像我们之前所说的变量一样,它是用来存储数据的。那它和变量存储数据有什么不同呢?

显然一个变量只能保存一份数据,在程序数据量小的情况下,使用起来比较方便。但是对于大规模的数据,单纯的变量就有点单薄了,对付大规模的数据,我们需要更强大的数据类型,将众多的变量凝聚在一起,也就构成了数组

简单的来说,数组就是同一类型数据的集合,下面就是定义的简单数组并对其进行初始化:

int a[5]={10,20};	//部分初始化
int a[5]={[4]=20,[2]=10}	//指定初始化
float c=['A'];
int m,g[10];	//若数组和变量的类型一致,可以放在一起定义

下面通过一个综合的小案例来加深一下对数组的基本操作。

//要求:由用户输入5个整数,保存到数组中,并按逆序打印所有元素。程序如下:
#include<stdio.h>
int main(){
	int i,a[5];
	printf("Please enter 5 integers:\n");
	for(i=0;i<5;++i)
		scanf("%d",&a[i]);	//将i作为下表值,给数组元素赋初值
	printf("Print array elements in reverse order:\n");
	for(i=4;i>=0;--i)
		printf("%d",a[i]);	//将i作为下标值,打印数组元素值
	return 0;
}

最后呢,对于数组的操作我们一定要切记不要越界访问,以免访问到数组之外的内存区域

2,数组作为函数参数

C 语言允许将数组作为函数的参数,即可以将数组名作为函数的实参进行传递。可以在参数名后面加上中括号的形式,表示该参数是一个数组类型。如下就是一个以数组为参数的函数PArray:

void PArray(int arr[]){
	for(int i=0;i<5;i++){
		arr[i]*=10;
		printf("%d ",arr[i]);
	}
}

3,字符数组

C 语言中,几乎所有的数据类型都可以被定义为数组。由于数组可以用来存储字符串,因此字符数组在C 语言中的运用极为广泛。

虽然C 语言中没有字符串这种数据类型,但它的运用却极为普遍,比如我们入手的第一个程序"hello world"。注意到,它是用双引号括起来的一段字符序列。另外,字符串还有一个重要的特征:字符串必须以空字符(用转义字符’\0’表示)作为结尾。即使是字符串常量,也会隐含地拥有这个空字符。例如:

"abc"	//这个字符串是由4个字符构成的,即字符a、b、c以及空字符,它的大小为4个字节

那我们是否会想,如何才能将"abc" 这个字符串存储到数组中呢?

//方法1:字符式存储
char str[4]={'a','b','c','\0'};	//全部初始化方式
char  str[4]={'a','b','c'};		//鉴于空字符的ASCII码值为0,也可采用部分初始化的方式

//方法2:字符串式存储
char  str[4]="abc";
//在实际编程中为了避免数组的长度不够这样的问题,我们通常建议采用下面这种方式进行赋值:
char str[]="abc";

在看了上述方法2之后,可能我们就在想如何才能得到一个字符串的长度是吗?

对于字符串,它除了有大小之外,还有长度的概念。我们这里就简单的区分一下:

字符串的大小指的是字符串所占内存的字节数,使用sizeof()库函数计算得出,而字符串长度则是指字符串中有效字符的个数,用strlen()库函数计算得出。所谓有效字符,就是除去作为结尾标记的空字符以外的字符。

4,二维数组

啊~~,五环,你比六环少一环~~~,顾名思义,二维数组就是在一维数组的基础上多了一维,简单的说就是多了一个"[ ]"。

至于对二维数组的初始化,与一维数组的初始化类似,下面就提一下行初始化方式

float score[3][3]={
	{88.5,86.5,96},		//第1行
	{88.5,86.5,96},		//第2行
	{88.5,86.5,96},		//第3行
}

前面说过一维数组可以作为函数参数,那类比一下,二维数组肯定也可以作为参数来进行函数调用。与一维数组作为函数参数时需要在参数名跟上一对中括号类似,二维数组需要两对中括号,其中第一对中括号用于表示第一维的大小,其值可以被省略,即使用空中括号形式;第二对中括号用于表示第二维的大小,其值不可被省略,即必须指明第二维的大小。 下面是一个打印二维数组所有元素的函数例子:

void printScore(float s[][4],int len){
	for(int i=0;i<len;i++){
		for(int j=0;j<4;j++)
			printf("%6.2f",s[i][j]);	//以6字符宽度、保留2位小数的格式打印
		printf("\n");		//打印一行元素后进行换行
	}
}

最后,我们可以用这样的思想来理解一下C 语言中的数组:

由普通元素(变量)构成的数组,是一维数组,即一维数组是普通元素(变量)的数组。

由一维数组构成的数组,是二维数组,即二维数组是一维数组的数组。

由二维数组构成的数组,是三维数组,即三维数组是二维数组的数组。

理解了数组的嵌套,再去理解指针与数组的关系,就会比较轻松了 ~ ~

实践中回顾(总结)

理解并掌握数组,会为后面的知识扩展打下坚实的基础。而真正掌握数组不能光靠理论知识,而是要更多的去实践,比较经典的题目有矩阵转置冒泡排序,下面就用一个经典的冒泡排序算法的实现来对数组的知识进行回顾。

编写程序,在数组中保存1~100的10个随机整数,对数组进行升序排序,并将排序后的数组元素打印输出,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
//冒泡排序
void bubble(int a[], int len) {
	int i, j, tmp;
	//1外层循环会执行 len - 1 次,表示共进行 len - 1 轮的比较过程
	for (i = 0; i < len - 1; ++i) {
		/*内层循环用于完成每一轮的比较过程。 它会从待排序序列中的第一个元素开始,逐个和后面的元素进行比较。另外, 随着外层循环中i 值的不断自增,表达式“len - 1-i”会使内层循环的 执行次数逐渐减少,这相当于把每轮完成后的最大值元素从待排序序列中排除*/
		for (j = 0; j < len - 1 - i; ++j) {
			if (a[j]> a[j + 1]) //检查前一个元素是否比后一个元素大 //如果是,就进行两个元素的值的互换 
			{
				tmp = a[j]; //将前一元素值赋给 tmp 
				a[j] = a[j + 1];//将后一个元素值赋给前一个元素 
				a[j + 1] = tmp;// 将 tmp 值赋给后一个元素 
			}
		}
	}
}
							
int main() {
	int i, arr[10]; //设置随机数种子
	srand(time(NULL)); //通过循环获取 10 个随机数,并将其保存到数组arr中 
	for (i = 0; i < 10; ++i)
		arr[i] = rand() % 100 + 1; //调用 bubble 函数进行冒泡排序,参数 1 为数组 arr,参数 2 为数组arr 的长度 
	bubble(arr, 10);
	//打印输出排序后数组中的各元素值 
	for (i = 0; i < 10; ++i)
		printf("%d ", arr[i]);
	return 0;
}

好了,经过上面的回顾,大家是否对C 语言中的数组有了一个更深的印象了呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阔升

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值