数组名的技术盲点

  • 数组首元素的地址和数组地址是两个不同的概念
  • 数组名代表数组首元素的地址,它是个常量。
    • 解释如下:变量本质是内存空间的别名,一定义数组,就分配内存,内存就固定了。所以数组名起名以后就不能被修改了。
  • 数组首元素的地址和数组的地址值相等
  • 怎么样得到整个一维数组的地址?
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. void main()
  6. {
  7. int a[] = { 1, 2};
  8. int b[100] = { 1, 3 };
  9. int c[200] = { 0 }; //编译时 就已经确定 所有的值 为零
  10. memset(c, 0, sizeof(c)); //显示的 重置内存块
  11. // 对一维数组C规定:
  12. // c 是数组首元素的地址 c+1 步长 4个字节
  13. // &c 是整个数组的地址 &c+1 步长 200*4
  14. system("pause");
  15. return;
  16. }

C语言规定:

  1. Int a[10];
  2. printf("得到整个数组的地址a: %d \n", &a); // 整个数组的地址
  3. printf("数组的首元素的地址a: %d \n", a); // 首元素的地址

怎么样表达int a[10]这种数据类型那?

数组类型、数组指针类型、数组指针类型变量

数组类型
  • 1数据类型分为基础、非基础,思考角度应该发生变化
  • 2 C语言中的数组有自己特定的类型
    • 数组的类型由元素类型和数组大小共同决定
    • 例:int array[5]的类型为int[5]
数组定义:
  1. typedef int(MYINT5)[5]; //int
  2. typedef float(MYFLOAT10)[10];
  3. MYINT5i Array; int array[5];
  4. MYFLOAT10fArray
定义数组类型,并用数组类型定义变量
  1. void main()
  2. {
  3. typedef int(MyArrayType)[5]; // 定义了一个数据类型 数组数据类型
  4. int i = 0;
  5. MyArrayType lessons;
  6. for (i = 0; i < 5; i++) {
  7. lessons[i] = i + 1;
  8. }
  9. printf("lessons:%d lessons+1:%d\n", lessons, lessons + 1); // lessons : 4193968 lessons + 1 : 4193972 步长4
  10. printf("&lessons:%d &lessons+1:%d\n", &lessons, &lessons + 1); // &lessons : 4193968 &lessons + 1 : 4193988 步长20
  11. system("pause");
  12. return;
  13. }

数组指针类型

  • 定义数组指针变量的方法1:用数组类型 加*
  1. void main()
  2. {
  3. char *MyArray[] = { "111","2222","3333" }; // 指针 数组
  4. typedef int(MyArrayType)[5]; // 定义了一个数据类型 数组数据类型
  5. int i = 0;
  6. MyArrayType lessons; // 数据类型 定义变量
  7. MyArrayType *pLessons; // 数据类型 定义一个指针变量 这个指针变量 指向一个数组
  8. {
  9. int a;
  10. int *p = NULL;
  11. p = &a;
  12. }
  13. {
  14. int lessons2[5];
  15. // 可以通过指针变量pLessons来操作lessons2的内存空间
  16. pLessons = &lessons2; // pLessons = &lessons;
  17. for (i = 0; i < 5; i++) {
  18. // lessons2[i] = i + 1;
  19. (*pLessons)[i] = i + 1;
  20. }
  21. for (i = 0; i < 5; i++) {
  22. printf("%d ", (*pLessons)[i]); // 1 2 3 4 5
  23. }
  24. }
  25. system("pause");
  26. return;
  27. }
  • 定义数组指针变量的方法2
  1. void main()
  2. {
  3. typedef int (*MyArrayType)[5]; // 定义了一个数组指针类型
  4. MyArrayType pLessons; // 告诉编译器 分配一个指针变量
  5. int c[5];
  6. int i = 0;
  7. pLessons = &c;
  8. for (i = 0; i < 5; i++) {
  9. (*pLessons)[i] = i + 1;
  10. }
  11. for (i = 0; i < 5; i++) {
  12. printf("%d ", (*pLessons)[i]); // 1 2 3 4 5
  13. }
  14. system("pause");
  15. return;
  16. }
  • 定义数组指针变量的方法3
    • 前面两种方法 通过类型定义 比较麻烦
    • 直接定义 int (*pLessons)[5]
  1. void main()
  2. {
  3. int c[5];
  4. int i = 0;
  5. int (*pLessons)[5]; // 直接定义了一个指向数组的 指针变量
  6. pLessons = &c;
  7. for (i = 0; i < 5; i++) {
  8. (*pLessons)[i] = i + 1;
  9. }
  10. for (i = 0; i < 5; i++) {
  11. printf("%d ", (*pLessons)[i]); // 1 2 3 4 5
  12. }
  13. system("pause");
  14. return;
  15. }

多维数组的本质

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<string.h>
  5. void printfArr1(int a[3][5])
  6. {
  7. int i, j, tmp = 0;
  8. for (i = 0; i < 3; i++)
  9. {
  10. for (j = 0; j < 5; j++)
  11. {
  12. printf("%d ", a[i][j]);
  13. }
  14. }
  15. return;
  16. }
  17. void printfArr2(int a[][5])
  18. {
  19. int i, j, tmp = 0;
  20. for (i = 0; i < 3; i++)
  21. {
  22. for (j = 0; j < 5; j++)
  23. {
  24. printf("%d ", a[i][j]);
  25. }
  26. }
  27. return;
  28. }
  29. //多维数组做函数参数的推演
  30. void printfArr3(int(*b)[5])
  31. {
  32. int i, j, tmp = 0;
  33. for (i = 0; i < 3; i++)
  34. {
  35. for (j = 0; j < 5; j++)
  36. {
  37. printf("%d ", b[i][j]);
  38. }
  39. }
  40. return;
  41. }
  42. void main()
  43. {
  44. int a[3][5];
  45. int i = 0, j = 0, tmp = 1;
  46. for (i = 0; i < 3; i++)
  47. {
  48. for (j = 0; j < 5; j++)
  49. {
  50. a[i][j] = tmp++;
  51. }
  52. }
  53. printf("\n-------------------\n");
  54. printfArr3(a);
  55. printf("\n-------------------\n");
  56. for (i = 0; i < 3; i++)
  57. {
  58. for (j = 0; j < 5; j++)
  59. {
  60. printf("%d ,", a[i][j]);
  61. }
  62. }
  63. printf("\na:%d , a+1:%d\n ", a, a + 1);//a+1的步长是20个字节 5*4
  64. printf("&a:%d , &a+1:%d\n ", &a, &a + 1);
  65. {
  66. //定义一个指向数组的指针变量
  67. int(*pArray)[5];//告诉编译器 分配4个字的内存 32bit平台下
  68. pArray = a;
  69. for (i = 0; i < 3; i++)
  70. {
  71. for (j = 0; j < 5; j++)
  72. {
  73. printf("%d,", pArray[i][j]);
  74. }
  75. }
  76. }
  77. /*
  78. 多维数组的本质 数组指针 ,步长 一维的长度
  79. (a) 代表是第0行的整个地址 (第一行的地址 和 第一行首元素的地址是重叠的。。。)
  80. (a+i) 代表是第i行的首地址 2级指针
  81. *(a+i) 代表 1级指针 第i行的首元素的地址
  82. */
  83. /*
  84. 转化推演:
  85. *( *(a+i) + j) ===>a[i][j] 元素的值
  86. a[i][j] <===> *(*(a+i)+j)
  87. a[i] ===> a[0+i] ===>*(a+i) 0是占位符
  88. a[i][j]===a[0+i][j] ==> *(a+i)[j] ===>*(a+i)[0+j] ===>* ( *(a+i) + j)
  89. **/
  90. system("pause");
  91. return;
  92. }