C语言重点笔记四——数组(一维数组,二维数组,数组类型,可变长数组,数组题目(矩阵,冒泡排序,顺序查找,二分查找)等)

本文详细介绍了数组的基本概念,包括一维数组和二维数组的定义、初始化、赋值、遍历以及数组的重要知识点。文中还涉及到C语言中的可变长数组,并给出了矩阵转置、冒泡排序等经典编程题目的实现,有助于加深对数组操作的理解。
摘要由CSDN通过智能技术生成

        

目录

一维数组相关笔记整理

二维数组相关笔记整理

数组定义方法

数组类型

数组重要知识点

可变长数组

相关题目练习(矩阵,冒泡排序,顺序查找,二分查找)


        数组就是一种新的数据结构,可以看作是一种装数据的容器,为了方便一次性多装点数据,而开发出来的一种数据结构。

        数组有个特点就是,一个数组只能装同一种数据,因为数据需要一定是确定数据类型,是不能放不同数据类型的数据的。学完数组后,其实字符串就是把字符放在数组里面,就成了字符串。

        数组中的数据是有序的,可以通过下标来访问某个元素;数据是同质的,所有元素必须具有相同的数据类型。

        数组特别要注意,赋值的时候,写得是数组的长度,例如int array[10]其中10是数组的长度,说明能放10个数。

        数组是连续存储的,所以数组就有坐标,也叫做索引,数组的索引从0开始到数组的长度-1结束,如array[10]

        其中第一个数据是array[0], 第十个数据是array[9]。

        这个时候特别要注意数组长度和索引最大值不是一个概念。

一维数组相关笔记整理:

        1.声明一维数组一般形式:数据类型  数组名[常量表达式]
    "[ ]"是数组的标志,"[ ]"中的常量表达式表示数组元素个数,即数组长度,常量表达式必须是正整数。eg.  int intArray[5];
    大多数情况下用命名常量来指定数组长度,更容易调整数组长度。eg. 1.#define ARRAY_SIZE 5            2.int intArray[ARRAY_SIZE];

        2.访问数组名方式:数组名[下标]。    访问数组时注意下标不能越界。

        3.数组的初始化式只能在一条语句中完成数组声明和初始化。eg.int intArray[5]={1,2,3,4,5};

        4.声明数组时,如果给定了数组的初始化式,则数组长度可以省略。

        5.数组初始化式中初始值可以小于数组长度,数组前面的元素被初始化为数组初始化式中对应的初始值,剩余元素被初始化为0。

        6.数组初始化式不能为空,初始值个数也不能大于数组长度。

        7.C99中指定初始化方法:int intArray[20]={[2]=20,[9]=8};    数组中intArray[2]=20,intArray[9]=8,其他元素为默认初始值0。

        8.数组大小/数组元素大小=数组长度

        9给数组元素赋值:    for(i=0;i<ARRAY_SIZE;++i)
                scanf("%d",&intArray[i]);

        10.使用memset()函数给整体赋值,必须包含string.h头文件。eg.将intArray数组所有元素均赋值为0:memset(intArray,0,sizeof(intArray));

        11.元素必须逐个进行复制,且目标函数(intSecondArray)长度大于或等于源数组(intArray)
    eg.    for(i=0;i<ARRAY_SIZE;i++)
            intSecondArray[i]=intArray[i];

        12.元素复制也可以使用标准函数库memcpy()进行复制。为了使用memcpy()函数,必须包含string.h头文件。
            eg.    memcpy(intSecondArray,intArray,sizeof(intArray));

二维数组相关笔记整理:

1.声明二维数组一般形式:
    数组类型 数组名[常量表达式][常量表达式2];
    eg. int intMatrix[3][2];    声明了一个名为intMatrix、3行2列、有6个元素的二维数组,每个元素都是int类型

 2.在声明二维数组式,可以使用嵌套的数组初始化式给数组元素赋初始值。
    eg.int intMatrix[3][2]={(1,2),(3,4),(5,6)};
       等价于:    int intMatrix[3][2];
            intMatrix[0][0]=1;
            intMatrix[0][1]=2;
            intMatrix[1][0]=3;
            intMatrix[1][1]=4;
            intMatrix[2][0]=5;
            intMatrix[2][1]=6;

 3.声明二维数组时,如果给定了初始化式,则数组行长度可以省略,但列长度不能省略。

 4.数组初始化式不能为空,初始值个数也不能大于数组长度。

 5.C99指定的初始化式对二维数组也有效。

数组定义方法:

以下数组的7种定义方法,一定要熟悉。

#include <stdio.h>

#include <time.h>

#include <stdlib.h>

#include "tools.c"

int main() {

// 单个赋值

int array[5];

array[0] = 10;

array[1] = 20;

array[2] = 30;

array[3] = 40;

array[4] = 50;

// printf("%d\n", array[0]);

// printf("%d\n", array[14]);



// 集体赋值

int array_1[5] = {11, 22, 33, 44, 55};

// printf("%d\n", array_1[0]);

// printf("%d\n", array_1[140]);



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

// printf("%d\n", array_2[0]);

// printf("%d\n", array_2[4]);



int array_3[5] = {0};

// printf("%d\n", array_3[0]);

// printf("%d\n", array_3[4]);



// int array_4[5] = {}; // 错误

// printf("%d\n", array_4[0]);

// int array_5[5] = {0, 1, 2, 3, 4, 5};    // 错误,超出数组存储数据的个数



int array_6[20] = {[2] = 22, [9] = 8, [14] = 58, [19] = 11};

// printf("%d\n", array_6[2]);

int array_7[20];

int i;

srand(time(NULL));

for(i=0; i<20; i++){

array_7[i] = 1 + rand() % 100;

}

return 0;

}

        数组其实是比较简单的,一维数组可以看作是excel表格中的一行,二维数组可以看做excel表格中的一张表。还有就是数组的长度和索引(也叫做位置坐标)之间的关系。所以无论是一维数组还是二维数组,都是从0开始,到长度-1结束。

 

索引

0

1

2

3

4

Array

100

200

300

400

500

索引

0

1

2

3

4

0

1

2

3

4

5

1

6

7

8

9

10

2

11

12

13

14

15

3

16

17

18

19

20

4

21

22

23

24

25

数组类型:

以下列举了各种类型的数组:

 

数组重要知识点

        数组就是个装数据的杯子,只是一次性可以装很多数据。要特别注意数组的赋值,数据的索引,数组的遍历(也就是打印数组),其实就是涉及到了循环和双重循环,那么双重循环我们在前面已经讲了很多了,画三角形和九九乘法表,都是用到双重循环,现在就是改头换面,但是代码没变,还是那些for循环代码。

要特别注意数组的赋值,数据的索引,数组的遍历(也就是打印数组)

数组作用:基本数据类型只能存放单个值,数组可以一次性放很多数据。

一个数组的数据在内存中是连续存放的。

数组就是一个容器,用来装数据的杯子。

                         大白话

1、赋值         把数据装进杯子

2、遍历         把数据倒出杯子,像数钱一样把数据一个个数出来  自己写的两个遍历函数

3、索引         数组是顺序存放,有坐标来指示每个数据位置

                      索引从0开始到   (长度-1)

 数组的遍历:

一维数组遍历用for

二维数组遍历用双层for

下面多加一个可变长数组,这个可以选择性了解:

1.数组长度有时候可以使用非常量表达式(可变长数组)
eg.    int n;
    scanf("%d",&n);
    int intArray[n];

2.可变长数组可以是多维的:
eg.    int n,m;
    scanf("%d%d",&n,&m);
    int intArray[n][m];

3.可变长数组的长度可以用任意整型表达式指定
eg.    int i,j,k;
    ...
    int a[3*i+5];
    int b[j+k];

4.可变长数组可以作为函数参数:
eg.    void reverseArray(int array[],int n){
    ...
}
    可变为:
    void reverseArray(int n,int array[n]){
    ...
}
使用可变长数组参数,可以明确指定数组array的长度就是n。

5.二维数组作为函数参数时,也可以使用可变长数组参数:
eg.    void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
    ...
}
    可变为:
    void transposeMatrix(int rowSize,int columnSize,int matrix[rowSize][columnSize]){
    ...
}

相关题目练习:

        最后是关于数组的一些经典题目,我根据自己的理解加上一些注释,希望对大家有帮助,若有错误也希望伙伴们提出来哇!下面可以结合上面的笔记进行学习:

(1)创建一个自定义大小的矩阵,然后将矩阵进行行列互换:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW_SIZE 10							//宏定义数组行长度 
#define COLUMN_SIZE 10						//宏定义数组列长度 
void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize);			//声明函数 
void printMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize);				//声明函数 
int main(){
	int matrix[ROW_SIZE][COLUMN_SIZE];					//声明数组及其大小 (最大行长度和最大列长度) 
	int row,column,n;									//声明数组行和列和矩阵的大小(即有效长度) 
	printf("输入矩阵的大小:");
	scanf("%d",&n);
	srand(time(NULL));
	for(row=0;row<n;++row){										//双重for循环为数组赋值 
		for(column=0;column<n;++column){
			matrix[row][column]=10+rand()%90;					//随机数填充数组matrix 
		}
	}
	printMatrix(matrix,n,n);								//调用函数
	transposeMatrix(matrix,n,n);							//调用函数 
	printf("行列互换后的矩阵:\n");
	printMatrix(matrix,n,n);								//调用函数 
	return 0;
} 														//注意上面函数调用顺序 


void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
	int row,column,temp;
	for(row=0;row<rowSize;++row){									//双重for循环进行数组行列互换 
		for(column=0;column<columnSize;++column){
			if(row<column){
				temp=matrix[row][column];
				matrix[row][column]=matrix[column][row];
				matrix[column][row]=temp;
			}
		}
	}
}


void printMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
	int row,column;
	for(row=0;row<rowSize;++row){
		for(column=0;column<columnSize-1;++column){							//columnSize-1在最后重新打印出来是因为要换行,所以格外打印 
			printf("%d ",matrix[row][column]);
			
		}
	printf("%d\n",matrix[row][columnSize-1]);					
	}
}

        代码中的void transposeMatrix()和void printMatrix()其实可以认为是两个功能,将自己想要的功能补充完整,再在main函数中直接调用该功能(函数)。

运行结果:

输入矩阵大小:4

63 32 90 32

54 50 23 64

86 18 79 93

95 45 21 51

行列互换后:

63 54 86 95

32 50 18 45

90 23 79 21

32 64 93 51

程序每次运行的结果可能不同。

(2)下面是大家熟悉的冒泡排序(自己的注释可能有点多,是自己的理解,大家选择性地看哈):

#include <stdio.h>
#define ARRAY_SIZE 4
void bubbleSort(int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
	int list[ARRAY_SIZE]={7,6,8,5};
	printf("排序前:");
	printArray(list,ARRAY_SIZE);							//调用函数把原数组打印出来 
	bubbleSort(list,ARRAY_SIZE);							//调用函数把原数组进行冒泡排序 
	printf("排序后:");
	printArray(list,ARRAY_SIZE);							//调用函数将冒泡排序后的数组打印出来 
	return 0;
} 
void bubbleSort(int list[],int arraySize){
	int pass,i,t,exchange;
	for(pass=1;pass<arraySize;++pass){
		exchange=0;
			for(i=0;i<arraySize-pass;++i){
				if(list[i]>list[i+1]){								//根据条件将元素位置进行交换 
					t=list[i];
					list[i]=list[i+1];
					list[i+1]=t;
					exchange=1;										//若前面满足条件执行到exchang=1后,返回++i继续循环,直到不满足for里面的条件才结束循环 
				}
			}										//for循环里面的元素 
			if(exchange==0)											//对于一开始就不满足第二个for里面的条件的元素,直接跳出来 
				break;
	}
}
void printArray(int list[],int arraySize){
	int i;
	for(i=0;i<arraySize-1;++i)
		printf("%d",list[i]);
	printf("%d\n",list[arraySize-1]);										//换行 
}
														//对于for循环过程:当arraySize=4时 
														//当pass=1时,i<3	√,	i++;
														//	lsit[i]>list[i+1]	i=0时,i<3	√	list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出 
														//	lsit[i]>list[i+1]	i=1时,i<3	√  list[1]>list[2]	成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出 
														//	lsit[i]>list[i+1]	i=2时,i<3	√	list[2]>list[3]	成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出 
														//	lsit[i]>list[i+1]	i=3时,i<3不成立,结束循环,回到pass++ 
	/*注意每次循环结束后同一下标的元素可能发生改变*/	//当pass=2时,i<2	√,i++;														
	/*即不同循环中的同一下标的元素不一样*/				//	lsit[i]>list[i+1]	i=0时,i<2	√	list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
														//	lsit[i]>list[i+1]	i=1时,i<2	√  list[1]>list[2]	成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
														//	list[i]>list[i+1]	i=2时,i<2不成立,结束循环,回到pass++
														//当pass=时3,i<1	√,i++;
														//	lsit[i]>list[i+1]	i=0时,i<1	√	list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出 												
														//	lsit[i]>list[i+1]	i=1时,i<1不成立,结束循环,回到pass++ 
														//当pass=4时,i<0 	√,i++ 
														//	list[i]>list[i+1]	i=0时,i<0不成立,结束循环 
														
														 

运行结果:

排序前:7 6 8 5

排序后:5 6 7 8

 

可以参考上图进行理解。

(3)顺序查找:顺序查找就是将要查找的元素(称为关键字)顺序与数组中的每个元素一一进行比较,直至关键字与数组某个元素匹配;或者与所有数组元素都比较完毕,未找到与关键字匹配的数组元素。

#include <stdio.h>
#define ARRAY_SIZE 10
int linearSearch(int key,int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
	int key,index;
	int list[ARRAY_SIZE]={1,4,4,2,5,-3,6,2,7,-8};					//数组list可容纳10个元素 
	printArray(list,ARRAY_SIZE);									//调用函数输出数组list的值 
	printf("输入需要查找的值:");
	scanf("%d",&key);
	index=linearSearch(key,list,ARRAY_SIZE);							//index表示的是该函数的返回值 
	if(index==-1)
		printf("查找失败!\n");
	else
		printf("查找成功:%d位于数组下标%d位置",key,index);
	return 0; 
} 

int linearSearch(int key,int list[],int arraySize){
	int i;
	for(i=0;i<arraySize;++i){										//通过for循环将key与数组list中的每个元素一一进行比较 
		if(key==list[i])
			return i;												//若找到匹配者,返回与关键字匹配的数组元素的下标 
	}
	return -1;														//若for循环没有找到满足条件的值,则最后返回-1 
}

void printArray(int list[],int arraySize){
	int i;
	for(i=0;i<arraySize-1;++i)
		printf("%d ",list[i]);
	printf("%d\n",list[arraySize-1]);
}

 

 

(4)二分查找:二分查找与顺序查找只是查找的函数功能有变化,其他基本没变。

#include <stdio.h>
#define ARRAY_SIZE 13
int binarySearch(int key,int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
	int key,index;
	int list[ARRAY_SIZE]={2,4,7,10,11,45,50,59,60,66,69,70,70};
	printArray(list,ARRAY_SIZE);
	printf("输入需要查找的值:");
	scanf("%d",&key);
	index=binarySearch(key,list,ARRAY_SIZE);
	if(index<0)
		printf("查找失败!\n");
	else
		printf("查找成功:%d位于数组下标%d位置",key,index);
	return 0;
		
} 													//下标:0 	1	2	3	4	5	6	7	8	9	10	11	12
int binarySearch(int key,int list[],int arraySize){		 //{2	4	7	10	11	45	50	59	60	66	69	70	70}
	int low,mid,high;									 
	low=0;
	high=arraySize-1;
	while(low<=high){							/*查找11过程: */
		mid=(low+high)/2;					//	一开始low=0,high=12,所以mid=6 ,对应的list[6]=50不等于11,而50>11,所有往前查找; 
		if(key<list[mid])					//	此时,low=0,high=mid-1=5,mid=(low+high)/2=2.5,但mid的数据类型为int,所以mid=2,对应的list[2]=7<11,所以往后查找; 
			high=mid-1;						//	此时,low=mid+1=3,high=5,所以 mid=(low+high)/2=4,对应的list[4]=11,所有11的位置即可得出,return mid 
		else if(key==list[mid])
			return mid;
		else
			low=mid+1;
	}
	return -1;									//	若数组里面的元素全部循环结束没有找到匹配的值,则返回-1 
}
void printArray(int list[],int arraySize){
	int i;
	for(i=0;i<arraySize-1;++i)
		printf("%d ",list[i]);
	printf("%d\n",list[arraySize-1]);
}

运行结果:

 2 4 7 10 11 45 5 59 60 66 69 70 70

输入需要查找的值:11

查找成功:11位于数组下标4位置

 2 4 7 10 11 45 5 59 60 66 69 70 70

输入需要查找的值:12

查找失败!

数组笔记分享到这啦!

有错误欢迎批评指正哈!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

تچ快乐杂货店يچ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值