一. 一维数组
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语言相关的问题可以通过私信发我 看到就会回的
下期再见~