2.3 二维数组的使用
二维数组的使用也是通过下标的方式。
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; 5. int i = 0; 6. int j = 0; 7. for (i = 0; i < 3; i++) 8. { 9. for (j = 0; j < 4; j++) 10. { 11. printf("%d ", arr[i][j]); 12. } 13. printf("\n"); 14. } 15. return 0; 16. }
调试结果:
2.4 二维数组在内存中的储存
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 }; 5. int i = 0; 6. int j = 0; 7. for (i = 0; i < 3; i++) 8. { 9. for (j = 0; j < 4; j++) 10. { 11. printf("%d %d %d %p\n ", i, j, arr[i][j], &arr[i][j]); 12. } 13. } 14. return 0; 15. }
调试结果:
总结: 二维数组在内存中也是连续的。
三、数组越界
数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,那么最后一个元素的下标就是n-1,所以数组的下标如果小于0,大于n-1,就是数组下标越界访问了,超出数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定会报错,但是编译器不报错,并不意味着程序就是正确的。
二维数组的行和列也可能存在越界。
c语言中也支持多维数组。例如:三维数组、四维数组等
四、数组作为函数参数
往往我们在写代码的时候,会将数组作为数组传个参数,比如:我要实现一个冒泡排序(这里要讲算法思想)函数。
设计一个函数对arr数组进行排序——冒泡排序的算法(bubble 动词:冒泡)
冒泡排序的思想:
两两相邻的元素进行比较,如果有可能的需要交换。
一趟冒泡排序只能解决一个数字 ,让当前待排序的的数组中的一个元素来到最终应该出现的位置上。 n个元素,需要n-1趟冒泡排序。第一趟n个待排序元素,第二趟n-1个元素,第三趟n-2个元素。
(1)确定趟数(2)内部操作,相邻两个元素交换
4.1 冒泡排序函数的设计
代码1展示:
1. #include <stdio.h> 2. void bubble_sort(int arr[],int a) 3. { 4. int i = 0; 5. int j = 0; 6. 7. for (i = 0; i < a - 1; i++)//确定趟数 8. { 9. for (j = 0; j < a - 1 - i; j++) 10. { 11. if (arr[j] > arr[j + 1]) 12. { 13. int b = arr[j]; 14. arr[j] = arr[j + 1]; 15. arr[j + 1] = b; 16. } 17. } 18. } 19. } 20. int main() 21. { 22. int arr[] = { 3,1,5,2,4,9,0,7,6,8 }; 23. int a = 0; 24. a = sizeof(arr) / sizeof(arr[0]); 25. bubble_sort(arr, a);//实际上数组传参,传递的不是整个数组,传递的是首元素地址 26. int i = 0; 27. for (i = 0; i < 10; i++) 28. { 29. printf("%d ", arr[i]); 30. } 31. return 0; 32. }
代码展示:(void bubble(int arr[], int a)可以写成void bubble(int* arr, int a))
1. #include <stdio.h> 2. void bubble_sort(int* arr,int a) 3. { 4. int i = 0; 5. int j = 0; 6. 7. for (i = 0; i < a - 1; i++)//确定趟数 8. { 9. for (j = 0; j < a - 1 - i; j++) 10. { 11. if (arr[j] > arr[j + 1]) 12. { 13. int b = arr[j]; 14. arr[j] = arr[j + 1]; 15. arr[j + 1] = b; 16. } 17. } 18. } 19. } 20. int main() 21. { 22. int arr[] = { 3,1,5,2,4,9,0,7,6,8 }; 23. int a = 0; 24. a = sizeof(arr) / sizeof(arr[0]); 25. bubble_sort(arr, a);//实际上数组传参,传递的不是整个数组,传递的是首元素地址 26. int i = 0; 27. for (i = 0; i < 10; i++) 28. { 29. printf("%d ", arr[i]); 30. } 31. return 0; 32. }
代码理解:
(1)函数里 第一个for 循环,是确定冒泡趟数。
(2)函数里 第二个for循环,是比较元素交换个数,10个元素就要进行9次比较;
(3)void bubble(int arr[], int a)可以写成void bubble(int* arr, int a) 实际上就是一个地址,不是整个数组。
知识点:
(1)实际上数组传参,传递的不是整个数组,传递的是首元素地址,所以在函数里sizeof(arr)的结果是4,所以在主函数的sizeof(arr)才是40,所以在主函数确定元素个数再传递到函数里面。
4.2 数组名是什么?
数组名是首元素地址。(有两个例外)
(1)sizeof内部单独放一个数组名,数组名表示整个数组。sizeof(数组名)计算的是整个数组的大小,单位是字节。 sizeof(arr) 这个就是特例,这里的arr就是整个数组,而不是首元素地址(2)&数组名,数组名表示整个数组,取出的是整个数组的地址。
代码展示:
1. #include <stdio.h> 2. int main() 3. { 4. int arr[5] = { 1,2,3,4,5 }; 5. printf("%p\n", arr);//数组名 6. printf("%p\n", &arr[0]);//数组首元素地址 7. printf("%p\n", &arr);//整个数组的地址 8. printf("%p\n", arr + 1);//第二个元素的地址 9. printf("%p\n", &arr[0] + 1);//第二个元素的地址 10. printf("%p\n", &arr + 1);//跨过一个数组的地址 11. return 0; 12. }
由于&arr是整个元素的地址,所以与&arr+1相错20个字节。相当于加了一个元素的地址。
数组知识点在这里就结束了。如果有问题的话,希望友友们可以提出宝贵的的意见。