hello!好久不见了,考试结束啦!我来更新知识了,这次会更新海量知识点,要上车的同学抓紧时间上车啦!!!我们还是接着上次的来说,希望大家多多支持,有什么要改进的地方评论区多多留言哦!
那让我们开始今天对数组的一个再认识吧!
1. 一维数组的创建和初始化
数组是一组相同类型元素的集合。
数组的创建方式:
1. type_t arr_name [const_n]; 2. //type_t 是指数组的元素类型 3. //const_n 是一个常量表达式,用来指定数组的大小
数组创建的实例:
1. //代码1 2. int arr1[10]; 3. //代码2 4. int count = 10; 5. int arr2[count];//数组时候可以正常创建? 6. //代码3 7. char arr3[10]; 8. float arr4[1]; 9. double arr5[20];
注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念。
1.2 数组的初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
看代码:
1. int arr1[10] = {1,2,3}; 2. int arr2[] = {1,2,3,4}; 3. int arr3[5] = {1,2,3,4,5}; 4. char arr4[3] = {'a',98, 'c'}; 5. char arr5[] = {'a','b','c'}; 6. char arr6[] = "abcdef";
数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。但是对于下面的代码要区分,内存中如何分配。
1. char arr1[] = "abc"; 2. char arr2[3] = {'a','b','c'};
1.3 一维数组的使用
对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。
我们来看代码:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[10] = {0};//数组的不完全初始化 5. //计算数组的元素个数 6. int sz = sizeof(arr)/sizeof(arr[0]); 7. //对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以: 8. int i = 0;//做下标 9. for(i=0; i<10; i++)//这里写10,好不好? 10. { 11. arr[i] = i; 12. } 13. //输出数组的内容 14. for(i=0; i<10; ++i) 15. { 16. printf("%d ", arr[i]); 17. } 18. return 0; 19. }
总结:
1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。
1. int arr[10]; 2. int sz = sizeof(arr)/sizeof(arr[0]);
1.4 一维数组在内存中的存储
接下来我们探讨数组在内存中的存储。
看代码:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[10] = {0}; 5. int i = 0; 6. int sz = sizeof(arr)/sizeof(arr[0]); 7. for(i=0; i<sz; ++i) 8. { 9. printf("&arr[%d] = %p\n", i, &arr[i]); 10. } 11. return 0; 12. }
仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。
由此可以得出结论:数组在内存中是连续存放的。
2. 二维数组的创建和初始化
1. /数组创建 2. int arr[3][4]; 3. char arr[3][5]; 4. double arr[2][4];
2.2 二维数组的初始化
1. //数组初始化 2. int arr[3][4] = {1,2,3,4}; 3. int arr[3][4] = {{1,2},{4,5}}; 4. int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略
2.3 二维数组的使用
二维数组的使用也是通过下标的方式。
看代码:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[3][4] = {0}; 5. int i = 0; 6. for(i=0; i<3; i++) 7. { 8. int j = 0; 9. for(j=0; j<4; j++) 10. { 11. arr[i][j] = i*4+j; 12. } 13. } 14. for(i=0; i<3; i++) 15. { 16. int j = 0; 17. for(j=0; j<4; j++) 18. { 19. printf("%d ", arr[i][j]); 20. } 21. } 22. return 0; 23. }
2.4 二维数组在内存中的存储
像一维数组一样,这里我们尝试打印二维数组的每个元素。
1. #include <stdio.h> 2. int main() 3. { 4. int arr[3][4]; 5. int i = 0; 6. for(i=0; i<3; i++) 7. { 8. int j = 0; 9. for(j=0; j<4; j++) 10. { 11. printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]); 12. } 13. } 14. return 0; 15. }
通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。
3. 数组越界
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的,所以程序员写代码时,最好自己做越界的检查。
1. #include <stdio.h> 2. int main() 3. { 4. int arr[10] = {1,2,3,4,5,6,7,8,9,10}; 5. int i = 0; 6. for(i=0; i<=10; i++) 7. { 8. printf("%d\n", arr[i]);//当i等于10的时候,越界访问了 9. } 10. return 0; 11. }
二维数组的行和列也可能存在越界。
4. 数组作为函数参数
往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法思想)函数将一个整形数组排序。
那我们将会这样使用该函数:
1. //方法1: 2. #include <stdio.h> 3. void bubble_sort(int arr[]) 4. { 5. int sz = sizeof(arr)/sizeof(arr[0]);//这样对吗? 6. int i = 0; 7. for(i=0; i<sz-1; i++) 8. { 9. int j = 0; 10. for(j=0; j<sz-i-1; j++) 11. { 12. if(arr[j] > arr[j+1]) 13. { 14. int tmp = arr[j]; 15. arr[j] = arr[j+1]; 16. arr[j+1] = tmp; 17. } 18. } 19. } 20. } 21. int main() 22. { 23. int i=0; 24. int arr[] = {3,1,7,5,8,9,0,2,4,6}; 25. bubble_sort(arr);//是否可以正常排序? 26. for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++) 27. { 28. printf("%d ", arr[i]); 29. } 30. return 0; 31. }
方法1,出问题,那我们找一下问题,调试之后可以看到 bubble_sort 函数内部的 sz ,是1。
难道数组作为函数参数的时候,不是把整个数组的传递过去?
4.2 数组名是什么?
1. #include <stdio.h> 2. int main() 3. { 4. int arr[10] = {1,2,3,4,5}; 5. printf("%p\n", arr); 6. printf("%p\n", &arr[0]); 7. printf("%d\n", *arr); 8. //输出结果 9. return 0; 10. }
数组名是数组首元素的地址(一般情况下)
如果数组名是首元素地址,那么:
1. int arr[10] = {0}; 2. printf("%d\n", sizeof(arr));
为什么输出的结果是:40?
补充:
1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。
4.3 冒泡排序函数的正确设计
当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,函数内部的 sizeof(arr) 结果是4。
如果 方法1 错了,该怎么设计?
1. //方法2 2. void bubble_sort(int arr[], int sz)//参数接收数组元素个数 3. { 4. 5. int i = 0; 6. for (i = 0; i < sz - 1; i++) 7. { 8. int j = 0; 9. for (j = 0; j < sz - i - 1; j++) 10. { 11. if (arr[j] > arr[j + 1]) 12. { 13. int tmp = arr[j]; 14. arr[j] = arr[j + 1]; 15. arr[j + 1] = tmp; 16. } 17. } 18. } 19. } 20. int main() 21. { 22. int i=0; 23. int arr[] = {3,1,7,5,8,9,0,2,4,6}; 24. int sz = sizeof(arr)/sizeof(arr[0]); 25. bubble_sort(arr, sz);//是否可以正常排序? 26. for(i=0; i<sz; i++) 27. { 28. printf("%d ", arr[i]); 29. } 30. return 0; 31. }
5. 数组实例:
5.1 数组的应用实例1:三子棋
5.2 数组的应用实例2:扫雷游戏
这两个实例在后面出专题来详细的讲解,希望不要错过哦!!!
好哒,今天的内容就到这里了,感谢大家的观看,谢谢大家,希望大家多多支持,我们一起学习,一起进步!!!