指针数组和指向数组的指针

  • 指针数组是另外开辟内存空间存放数组,而指向数组的指针是一个数组的首地址的别名,所以可以通过*(p+?)的形式获取其他数组元素
  • 指针数组是一连串指针的总称,而指向指针的数组是一个指针

  • 数组是存储一个固定大小的相同类型元素的顺序集合。所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。
  • 数组通过下标来访问数组元素,从[0]开始

    声明数组

    在 C 中要声明一个数组,需要指定元素的类型和元素的数量,声明时并初始化可以省略元素数量

  • 声明一维数组:**type arrayName [ arraySize ];**arraysize>=0的整数常量

  • 声明多维数组:如**int threedim[5][10][4];[?]数量任意**
  • 多维数组声明与初始化一起时可以省略第一个[]大小

    初始化数组

    一维数组

  • 可以逐个初始化

  • 或者声明时初始化:double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};

    • {}内元素数量<=arraySize
    • 此种方式创建数组可以省略数组大小,大小为{}元素个数
    • 字符型数组还可以这样**char greeting[] = "Hello";相当于gree[5]={'H',...}**

      多维数组

      int a[3][4] = {
      {0, 1, 2, 3} , /* 初始化索引号为 0 的行 */
      {4, 5, 6, 7} , /* 初始化索引号为 1 的行 */
      {8, 9, 10, 11} /* 初始化索引号为 2 的行 */
      };
      等价于:int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

      数组大小与长度

      一维数组

  • 获取数组长度:sizeof(ArrayName)/sizeof(ArrayName[?])

    • sizeof获取的是整个数组的内存大小,所以要除以数组任意一个元素的大小
    • 数组大小为元素数数据类型大小,如`double a[5];sizeof(a[1])=8即一个double变量的大小 则sizeof(a)=58=40`
    • **一维数组里,sizeof(a[1000])都可以得到想要结果**因为sizeoof不关心参数是否存在,只关注它的类型;
      • 而在二维数组里如a[2][3],a[?]代表行。而sizeof(a[1000])=sizeof(a[0])=type*3 同样sizeof不关心a[1000]是否存在

        数组与指针(重点)

  • 数组名也代表数组首地址,即a=&a[0]=&a int *a=a[0]=*(&a[0]),所以sizeof(a)=sizeof(*a)=sizeof(a[0])=sizeof(&a[0])

    • 访问数组时不能直接用a表示a[0] 访问数组元素只能通过下标或者地址与指针 即如果要用a来获取数组个元素的值,得借助指针 如*(a+?)
    • 指针名代表指针首地址,所以可以a[2]=*(a+2)

      数组与函数串

      传递数组给函数

  • 如果您想要在函数中传递一个一维数组作为参数,您必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。

    • (不知道为什么是整型指针,可能是任何类型的数组其地址都是整型吧)
  1. 形参为指向数组的指针:**? myFunction(int *param){...}**
  2. 形式参数是一个已定义大小的数组:**? myFunction(int param[10]){...}**
  3. 形式参数是一个未定义大小的数组:**? myFunction(int param[]){...}** ```c double getAverage(int arr[], int size) { int i; double avg;//平均值 double sum;//数组总和

    for (i = 0; i < size; ++i) { sum += arr[i]; }

    avg = sum / size;

    return avg; }

    include

/ 函数声明 / double getAverage(int arr[], int size);

int main () { / 带有 5 个元素的整型数组 / int balance[5] = {1000, 2, 3, 17, 50}; double avg;

/ 传递一个指向数组的指针作为参数 / avg = getAverage( balance, 5 ) ;

/ 输出返回值 / printf( “平均值是: %f “, avg );

return 0; }

结果:平均值是214.400000

  1. 有一个坑,改为第二种形式,此时可以正确输出214.如果进一步将5改为sizeof(a)/sizeof(a[0])的形式就输出不了正确的结果,比如515204...
  2. <a name="IX9mm"></a>
  3. ## 从函数返回数组
  4. **C 语言不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针**
  5. - **从函数返回一个一维数组,你必须声明一个返回指针的函数**`**int* myFunction(){...}**`
  6. ```c
  7. #include <stdio.h>
  8. 返回一个int型指针,return则返回
  9. int * getRandom( )
  10. {
  11. static int r[10];
  12. int i;
  13. /* 设置种子 */
  14. srand( (unsigned)time( NULL ) );
  15. for ( i = 0; i < 10; ++i)
  16. {
  17. r[i] = rand();
  18. printf( "r[%d] = %d\n", i, r[i]);
  19. }
  20. //循环输出数组元素
  21. return r;
  22. }
  23. /* 要调用上面定义函数的主函数 */
  24. int main ()
  25. {
  26. /* 一个指向整数的指针 */
  27. int *p;
  28. int i;
  29. p = getRandom();
  30. for ( i = 0; i < 10; i++ )
  31. {
  32. printf( "*(p + %d) : %d\n", i, *(p + i));
  33. }
  34. return 0;
  35. }
  • 函数是返回一个int型指针,return语句返回的是数组首地址(即数组名) 这里必须是int,因为是地址
  1. 主函数内再定义一个int型指针接收函数返回的数组首地址。然后通过***(p+数字)**表示下标来访问数组元素
  2. C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。所以如果是在函数内定义的数组,记得设置为static类型