小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2025-11-05 / 6 阅读
0
0

C语言指针与数组笔记

C语言指针与数组笔记

1. 指针数组 (Array of Pointers)

  • 本质:数组,每个元素都是指针
  • 声明语法类型 *数组名[大小]

声明示例

int *ptr_arr[5];        // 5个整型指针的数组
char *str_arr[3];       // 3个字符指针的数组
float *float_arr[10];   // 10个浮点指针的数组

使用示例

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;
    int *ptr_arr[3] = {&a, &b, &c};
  
    // 读取方式
    for(int i = 0; i < 3; i++) {
        printf("ptr_arr[%d] = %p\n", i, ptr_arr[i]);     // 指针值(地址)
        printf("*ptr_arr[%d] = %d\n", i, *ptr_arr[i]);   // 解引用
        printf("*(ptr_arr + %d) = %d\n", i, *(ptr_arr[i])); // 等价写法
    }
    return 0;
}

字符串指针数组(常用)

char *fruits[] = {"Apple", "Banana", "Orange"};
for(int i = 0; i < 3; i++) {
    printf("fruits[%d] = %s\n", i, fruits[i]);
}

2. 数组指针 (Pointer to Array)

  • 本质:指针,指向整个数组
  • 声明语法类型 (*指针名)[大小]

声明示例

int (*arr_ptr)[5];      // 指向包含5个整数的数组
char (*char_ptr)[10];   // 指向包含10个字符的数组

使用示例

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int (*arr_ptr)[5] = &arr;  // 取整个数组的地址
  
    // 三种等价的读取方式
    for(int i = 0; i < 5; i++) {
        printf("(*arr_ptr)[%d] = %d\n", i, (*arr_ptr)[i]);  // 推荐
        printf("arr_ptr[0][%d] = %d\n", i, arr_ptr[0][i]);
        printf("*(*arr_ptr + %d) = %d\n", i, *(*arr_ptr + i));
    }
    return 0;
}

3. 多维数组指针

指向整个二维数组

int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

// 指向整个3x4二维数组
int (*mat_ptr1)[3][4] = &matrix;

// 读取方式
for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 4; j++) {
        printf("(*mat_ptr1)[%d][%d] = %d\n", i, j, (*mat_ptr1)[i][j]);
    }
}

指向行(更常用)

// 指向包含4个整数的行
int (*row_ptr)[4] = matrix;  // 等价于 &matrix[0]

// 读取方式
for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 4; j++) {
        printf("row_ptr[%d][%d] = %d\n", i, j, row_ptr[i][j]);
    }
}

函数参数中的多维数组指针

// 接收二维数组指针作为参数
void print_matrix(int (*arr)[4], int rows) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < 4; j++) {
            printf("%2d ", arr[i][j]);
        }
        printf("\n");
    }
}

// 调用
print_matrix(matrix, 3);

4. 关键区别总结

类型 声明 含义 内存布局
指针数组 int *arr[5] 5个int指针的数组 [ptr1, ptr2, ptr3, ptr4, ptr5]
数组指针 int (*arr)[5] 指向5个int数组的指针 ptr → [int, int, int, int, int]
二维数组指针 int (*arr)[4] 指向4个int数组的指针 ptr → [int×4], 可递增到下一行

5. 记忆技巧

运算符优先级规则

int *arr[5];    // []优先级高:指针的数组
int (*arr)[5];  // ()改变优先级:数组的指针

阅读技巧:从内向外,从右向左

int *ptr[5];    // ptr是数组[5],元素是int指针
int (*ptr)[5];  // ptr是指针,指向int数组[5]

6. 综合示例

#include <stdio.h>

int main() {
    // 1. 指针数组
    int a=1, b=2, c=3;
    int *ptr_arr[] = {&a, &b, &c};
  
    // 2. 数组指针  
    int arr[3] = {10, 20, 30};
    int (*arr_ptr)[3] = &arr;
  
    // 3. 二维数组指针
    int matrix[2][3] = {{1,2,3}, {4,5,6}};
    int (*mat_ptr)[3] = matrix;
  
    printf("指针数组:\n");
    for(int i=0; i<3; i++) 
        printf("%d ", *ptr_arr[i]);
  
    printf("\n数组指针:\n");
    for(int i=0; i<3; i++)
        printf("%d ", (*arr_ptr)[i]);
  
    printf("\n二维数组指针:\n");
    for(int i=0; i<2; i++) {
        for(int j=0; j<3; j++) {
            printf("%d ", mat_ptr[i][j]);
        }
    }
  
    return 0;
}

核心要点:理解声明中的优先级,明确操作的是指针还是数组。


评论