c语言数组

发布于:2022-12-26 ⋅ 阅读:(462) ⋅ 点赞:(0)

一. 一维数组

1. 一维数组的创建

1 数组是什么?(数组的定义)
数组是相同类型元素的集合

2 数组的创建方式


int main()
{
	//数组的创建方式
	// type_t  arr_name [const_n}
	// type_t 是指数组的元素类型
	// const_n 是一个常量表达式 用来指定数组的大小
	return 0;
}

不过这里有一点要注意的是 在c语言的c99标准中支持了变长数组的概念 即数组的大小可以使用变量指定
但是数组不能初始化

2. 一维数组的初始化

1 什么是初始化?
初始化就是指 在创建数组的同时给数组内的内容一些合理化的数值
2 写出一些数组初始化的代码
代码如下

int main()
{
	int arr1[10] = { 1,2,3 };
	int arr2[] = { 1,2,3,4 };
	int arr3[5] = { 1,2,3,4,5 };
	char arr4[3] = { 'a',98,'c' };
	char arr5[] = { 'a','b','c' };
	char arr6[] = "abcdef";
	return 0;
}

3 请区分以下两个数组有多少个元素

	char arr1[] = "abc";
	char arr2[] = { 'a','b','c' };
	char arr3[3] = { 'a','b','c' };
	char arr4[5] = { 'a','b'};

正确答案 应该是 4 3 3 5
大家可以使用sizeof操作符验证一下
至于为什么arr1[]的大小是4呢?
其实是因为在初始化字符串“abc”的时候后面有个默认的转义字符\0
它的ascll码值是0 占一个字节
所以arr1才占四个字节的大小

4 扩展题

	char arr1[] = "abc";
	char arr2[] = { 'a','b','c' };
	char arr3[3] = { 'a','b','c' };
	char arr4[5] = { 'a','b'};

它们的字符串长度分别是多少呢?
为什么?

正确答案是 3 随机数 随机数 2
strlen的脾气比较倔 不知道变通 它统计字符串长度的时候一定要遇到’\0’才肯罢休
arr1上面已经讲解了 它的第四个字符是\0 所以说返回值是3
arr2呢 数组后面的值是随机值 并不知道什么时候会遇到‘\0’ 所以说会返回一个随机值
arr3呢 虽然数组初始化为3了 但是strlen一定要找到’\0‘才会停止 所以说会返回一个随机值
arr4呢 数组未完全初始化 而后面的值会默认初始化为0 我们上面讲过了 ’\0‘的ascll码值就是0 所以说返回的长度是2

3. 一维数组的使用

对于数组的使用我们介绍操作符的时候介绍了:[],下标引用操作符

int main()
{
	int arr[10] = { 0 };//数组的不完全初始化
	// 计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//对数组内容赋值 
	int i = 0;
	for ( i = 0; i < sz; i++)
	{
		arr[i] = i;
	}
	for ( i = 0; i < sz; i++)
	{
		printf("%d\n", arr[i]);
	}
	return 0;
}

总结一下
1 数组是使用下标来访问的 下标打大小是从0开始的
2 数组的大小是可以通过计算得到的 计算公式如下

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

4. 一维数组在内存中的存储

代码如下

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (  i = 0; i < sz; i++)
	{
		printf("%p\n", &arr[i]);
	}
	return 0;
}

输出结果如下
在这里插入图片描述
观察输出结果 我们可以得到以下结论

一维数组在内存中是连续存放的

二. 二维数组

1. 二维数组的创建

代码如下

int arr[3][4];
char arr2[3][4];
double arr[2][4];

2. 二维数组的初始化

这里需要注意的一点是 二维数组初始化的时候行可以省略 列不可以省略

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

3. 二维数组的使用

代码如下


int main()
{
	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for ( i = 0; i < 3; i++)
	{
		int j = 0;
		for ( j = 0;  j < 5;  j++)
		{
			printf("%d\n", arr[i][j]);
		}

	}
	return 0;
}

4. 二维数组在内存中的存储

代码如下

int main()
{
	int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%p\n", &arr[i][j]);
		}

	}
	return 0;
}

结果如下
在这里插入图片描述
由此我们可以得出结论
二维数组在内存中是连续存储的

联合一维数组在内存中存储的结论 我们可以大胆推断出
数组在内存中是练习存储的

三. 数组越界

数组的下标是有范围限制的。
数组的下标从0开始 如果数组有n个元素 则最后一个元素的下标就是n-1
所以数组的下标如果小于0 或者大于n-1 就是数组越界访问了 超出了数组合法空间的访问
c语言本身不错下标的越界检查 编译器也不一定报错
所以我们在写数组的时候要自己检查 以免犯错

四. 数组作为参数传参

1. 冒泡排序实现数组排序

实现代码如下

void bubble_sort(int arr[10], int sz)
{
	int i = 0;
	for ( i = 0; i < sz-1; i++)
	{
		int j = 0;
		for (  j = 0; j <sz-1-i; j++)
		{
			if (arr[j]>arr[j+1])
			{
				int tmp = arr[j+1];
				arr[j + 1] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}

int main()
{
	int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for (size_t i = 0; i < sz; i++)
	{
		printf("%d\n",arr[i]);
	}
	return 0;
}

这里博主写这段代码的时候出现了一点失误
在最后j循环交换的时候写成了

int tmp = arr[i+1];

最终导致找了好久都没有发现错误
希望大家写代码的时候还是要细心啊

这里还有一个注意点
sz的计算必须要在主函数内计算 而不能在冒泡排序计算
因为arr传递的是数组的首元素地址 而不是整个数组
具体的细节 博主在函数栈帧中有详细解释 大家感兴趣的话可以去看看
函数栈帧

2. 数组名是什么?

数组名在大部分情况下表示的是首元素地址
两张情况下除外

1 在sizeof(arr)中 arr表示是整个数组
2 在&arr中 arr表示的也是整个数组

可能有些同学会好奇 &arr的结果打印出来明明是首元素地址啊 那这为什么和arr[0]不同呢?

我们说:当创建两个指针分别指向arr和arr[0]的时候
指向arr的指针每次移动的大小是整个数组的大小
指向 arr[0]的指针每次移动的大小是元素所占空间的大小

以上
由于本人知识的不足可能出现各种错误 希望大佬看到可以在评论区指出
如果有c语言相关的问题可以通过私信发我 看到就会回的
下期再见~

本文含有隐藏内容,请 开通VIP 后查看