C语言数组

C语言数组,第1张

数组: 一、数组初始化:
int a1[5] = {1, 2, 3, 4, 5};
int a3[] = {1, 2, 3};//OK,自动根据给定的初始化列表的元素个数,来分配数组的长度
int a4[5] = {1, 2, 3};//OK,只初始化数组元素的一部分,另外的默认初始化为0

//int a2[5] = {1, 2, 3, 4, 5, 6};//错误,越界了
注意:

C99之前,不能用变量来作为数组定义[]里面的内容
C99之后,能用变量来作为数组定义[]里面的内容,但是不能在定义的时候做初始化

二、数组名的含义

数组名代表的是首元素的地址,可以通过地址偏移,解引用的方式,拿到数组元素的值

访问数组的元素,通过下标:
a[1] 通过数组下标为1,访问到数组的元素

访问数组的元素,可以通过地址偏移
*(a+1) 通过地址偏移的方式,访问到数组的元素

int arr[5];
//arr:访问首元素的地址
//&arr:整个数组的地址

地址偏移访问数组元素
int arr[3] = {1,2,3};
for (int i = 0; i < 3; ++i)
	{
		sum += *(arr+i);
	}
	printf("所有元素之和为:%d\n", sum);

三、一维数组

一维数组的定义和初始化
如果我们定义一个数组,想要全部元素初始化为0
int arr[5] = {0};
而不是:
int arr[5];或者int arr[5] = {};
这样去定义一个数组,数组元素是没有做初始化的,不能确定里面的元素值是多少

一维数组的传参
数组传参的时候,本质上传入的是首元素的地址,在函数里面,还是通过首元素的地址来访问所有的元素的值

void func1(int a[])   //通过数组接收函数传参的首元素地址
{
	for (int i = 0; i < 3; ++i)
	{
		printf("a[%d] = %d\n", i, a[i]);
		// printf("a[%d] = %d\n", i, *(a+i));
	}
}

void func2(int *a)   //通过指针接收函数传参的首元素地址
{
	for (int i = 0; i < 3; ++i)
	{
		//printf("a[%d] = %d\n", i, a[i]);
		printf("a[%d] = %d\n", i, *(a+i));
	}
}
注意:

数组传参,传首元素的地址,函数在以数组方式接收到数组的首元素的地址的时候,函数里面会自动将这个数组退化成指针。


一般在通过函数传递数组的时候,一般需要将这个数组的长度传递给函数

四、二维数组(多维数组) 二维数组的定义 示例:
int arr[2][3];

    代码释义:
	arr[2]:数组的定义,数组元素有两个
	int [3]:数组的元素的类型,表示的是该数组是一个具有三个元素的整型一维数组
二维数组初始化

多维数组跟普通的一维数组的语法完全一致

int arr[2][3] = {{1,2,3}, {4,5,6}};
	
	// int arr1[2][3] = {{1,2,3}, {4,5,6}, {7,8,9}};//错误,越界了
	// int arr2[2][3] = {{1,2,3}, {4,5,6,7}};//错误,越界了
	int arr3[2][3] = {{1,2,3}};		//ok,只初始化一部分,未初始化的默认初始化为0

	int arr4[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};//OK,元素的个数通过给的元素来确定
	// int arr5[3][] = {{1,2,3}, {4,5,6}, {7,8,9}};//错误,一维数组的长度不确定
	// int arr6[][] = {{1,2,3}, {4,5,6}, {7,8,9}};//错误,理由同上
二维数组的元素访问
int arr[2][3] = {{1,2,3}, {4,5,6}};

	printf("arr[0][1] = %d\n", arr[0][1]);//2
	printf("arr[0][1] = %d\n", arr[1][2]);//6
		
	printf("arr[0][1] = %d\n", *(*(arr+1)+2));

	// printf("arr[0][1] = %d\n", arr[2][2]);//错误,越界了
数组的万能拆解法:

任意的数组,不管多复杂,其定义都是由两部分组成的
第一部分:数组的名字,数组元素个数
第二部分:说明元素的类型,可以是任意的类似

示例:
int a[3];  		//第一部分:a[3];	第二部分:int
int b[3][4];	//第一部分:b[3];	第二部分:int [4]
int c[3][4][5];	//第一部分:c[3];	第二部分:int [4][5]		第三部分:int [5]
int *d[6];		//第一部分:d[6];	第二部分:int *
int (*e[7])(int, int);	//第一部分:e[7];	第二部分:int (*)(int, int)

上述示例中:a[3],b[3],c[3],d[6],e[7]本质上并无区别,他们均是数组
上述示例中:a[3],b[3],c[3],d[6],e[7]唯一的区别,是他们所存放的元素的数据类型不同

二维数组的传参

基本数据类型(字符数据除外),组合数据类型都可以按照这种方式

void func1(int arr[][3])//数组接收传递的参数
{

}

// void func2(int (*arr)[])    //(*arr)[]叫做数组指针
void func2(int (*arr)[3])   //(*arr)[3]叫做数组指针
{

}

int main(int argc, char const *argv[])
{
	int arr[2][3] = {{1,2,3}, {4,5,6}};
	func1(arr);
	func2(arr);	
}

字符数组传参
// void func1(char *arr[])
void func1(char **arr)
{
	printf("arr[0] = %s\n", arr[0]);
	printf("arr[1] = %s\n", arr[1]);	
}


void func2(char arr[][20])   //数组接收传递的参数
// void func2(char (*arr)[20])  //(*arr)[3]叫做数组指针
{
	printf("arr[0] = %s\n", arr[0]);
	printf("arr[1] = %s\n", arr[1]);
}

int main(int argc, char const *argv[])
{
	char *arr1[20] = {"hello", "world"};
	char arr2[][20] = {"hello", "world"};

	func1(arr1);
	func2(arr2);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/662708.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-18
下一篇 2022-04-18

发表评论

登录后才能评论

评论列表(0条)

保存