C语言 进阶指针学习笔记-数组指针

时间:2025-03-10 11:07:02

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

int main()  
{  
    int *arr1[5]; // 指针数组  
    // arr1 先是一个数组(先和方块结合),数组中的每个元素都是一个 int*,指向 int 类型的变量  
  
    int (*arr2)[5]; // 数组指针  
    // arr2 是一个指针,指向一个 int 类型的数组  
    return 0;  
}

数组名

  1. 通常,数组名表示的都是首元素地址
  2. 存在两个例外
    1. sizeof (数组名),这里的数组名表示整个数组
    2. &数组名,表示的依然是整个数组

类型(对 int arr[5]]):

  • arr -> int*
  • &arr -> int (*)[5]
#include <stdio.h>  
  
int main()  
{  
    int arr1[] = {1, 2, 3, 4, 5};  
    printf("%p\n", arr1);  
    printf("%p\n", &arr1);  
    // 在这里,&arr1 表示整个数组的地址,即 arr1 的地址  
  
    printf("----------------\n");  
  
    int sz = sizeof(arr1);    printf("%d\n", sz);    // sizeof(arr1) 是整个数组的大小,单位是字节  
    // 在这里,数组名表示整个数组  
  
    printf("----------------\n");  
  
    printf("%p\n", arr1 + 1);    printf("%p\n", &arr1 + 1);    // arr1 + 1 表示数组中第二个元素的地址  
    // &arr1 + 1 表示整个数组后面的地址  
  
    printf("----------------\n");  
  
    int (*parr)[5] = &arr1;    // parr 是一个指针,指向一个 int 类型的数组  
    // 需要写清楚有几个元素
    // 此时,parr 的类型为 int(*)[5]
  
    int *p = &arr1;  
    // warning:'int(*)[5]' 类型的表达式被隐式转换为不兼容的指针类型  
  
    return 0;  
}

数组传参

#include <stdio.h>  
  
/**  
 * @brief 打印数组内容,参数直接传数组  
 *
 * @param arr 传入数组  
 * @param line 数组行数  
 * @param length 数组列数  
 */void print1(int arr[3][5], int line, int length)  
{  
    for (int i = 0; i < line; i++)  
    {  
        for (int j = 0; j < length; j++)  
        {  
            printf("%d ", arr[i][j]);  
        }  
        printf("\n");  
    }  
}  
  
  
/**  
 * @brief 打印数组内容,传参传数组指针  
 * * @param p   
 * @param line   
 * @param length   
 */  
void print2(int (*p)[5], int line, int length)  
{  
    for(int i = 0; i < line; i++)  
    {  
        for(int j = 0; j < length; j++)  
        {  
            printf("%d ", *(*(p + i) + j));  
            // printf("%d ", (*(p + i))[j]); // 等价于上面的写法  
            // 如果写成 *(p + i)[j],输出会报错,因为 [] 的优先级高于 *            printf("%d ", p[i][j]); // 也可以这样写  
        }  
        printf("\n");  
    }  
}  
  
int main()  
{  
    int arr[3][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};  
    // 二维数组的首元素是第一行,在这里为含有 5 个元素的一维数组  
  
    print1(arr, 3, 5);  
    print2(arr, 3, 5); // 将二维数组的首元素传入函数  
  
    return 0;  
}
int *parr1[10];
// 指针数组

int(*parr)[10];
// 数组指针

int(*parr[5])[10];
// 存放数组指针的数组

一维指针数组传参
指针数组元素为 指针
指针数组的数组名相当于一个 指针
指针指向存放一个指针的位置 -> 二级指针
因此指针数组传参可以为二级指针

void test(int **parr);

void test1(int *parr[20]);

二维数组通过指针传参
二维数组的首元素是一维数组,不能用一级/二级指针接收
形参应该是一个一维数组的指针

void test(int *arr);
// err

void test1(int (*arr)[5]);
// 参数为一个一维数组

void test2(int **arr);
// err,二级指针指向存放一级指针的地址,不能是指向一个一维数组的指针