C语言入门 – 指针与数组的转换

LongGuan_admin 发布于 15 小时前 7 次阅读


数组指针

在一个一维数组中,定义一个int buf {}; 定义一个指针 int *p = buf;

指针P存储int类型的buf的数据, p存储了buf的值,所以p与buf的值相等

  • 声明时意义不同
  • sizeof时,p与buf值不相同
  • &取地址时,p与buf值不同
// 1. sizeof时 p 与 buf值不相同
    printf("%ld \n", sizeof(buf));
    printf("%ld \n", sizeof(p));
// 2. &取地址时 p 与 buf值不相同
    printf("%p \n", &buf);
    printf("%p \n", &p);

数组指针, 存储的是整个数组的地址

本身buf的类型为int[10] 指向其类型的指针 int (*)[10]

int (*p1)[10] = &buf;
printf("%d \n", (*p1)[2]);
printf("%d \n", p1[0][2]);
  • []的优先级高于*
    • int *p2[] 是一个数组,存储int型的地址
    • int (*p1)[10] = &buf; 是一个指针,指向数组的地址
int (*p1)[10]  = &buf; 

二维数组和指针之间的转换

  • 定义了一个二维数组int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    int (*p)[4] = arr;
    int (*p1)[3][4] = &arr;

    printf("%d \n", p[1][2]);
    printf("%d \n", *(*(*p1 + 1) + 2));
    printf("%d \n", (*p1)[1][2]);
    printf("%d \n", p1[0][1][2]);

    // q是一个数组长度为4,里面的元素类型int *
    int a = 12;
    int *q[4] = {&a};
    // int *q1[3][4] q1是个数组长度为3,
    // 子元素类型int *[4] 这个类型是数组类型,数组子元素类型 int *
    int *q1[3][4] = {{&a}, {&a, &a, &a, &a}, {&a}};
    //  int (*q2[3])[4] 数组子元素类型 int (*)[4] 指针指向长度为4 int型数组
    int (*q2[3])[4];
    */

    // int arr[3];

    // int *p = arr;

    // char arr[3];
    // char *p = arr;

    char *arr[3] = {"hello", "world", "aaa"};
    char **p = arr;

    printf("%s \n", arr[0]);
    printf("%c \n", arr[0][1]);
    printf("%s \n", arr[1]);
    printf("%s \n", p[0]);
    printf("%c \n", p[0][1]);
    printf("%s \n", p[1]);
  • 在定义语句中,判断这个变量是数组还是指针通过运算符的优先级判断:
    •  ()  >  [ ]   >  *
    • 如果变量首先粘住的是[ ]
      • 那么这个变量一定是一个数组
    • 如果变量首先粘着的是*
      • 那么这个变量一定是一个指针
  • 判断一个指针变量的类型,变量名遇到*号的时候,记住,一定要停下来,剩余的东西都是用来修饰这个指针所指向的内容是怎么样的
    • 比如:char *(*p)[3] = &buf;  // p 指向 char * [3] 指针数组 //p ---指针数组指针
    • 比如:char (**p)[3];  // p 指向 char (*) [3] 数组指针 //p ---数组指针指针
    • 比如:char **p[3];  // p 数组 char ** 二级指针// p ---二级指针数组

野指针

  • 指针只声明没有初始化
    • 其值是一个随机数
      • int *p; *p = 5;
      • 此时p是野指针
  • 指针所指向的内存被系统回收但仍然进行访问
  • 指针越界
  • 野指针的危害
    • 访问非法内存,会导致段错误
    • 可能破坏系统的关键数据,导致系统崩溃等严重错误
  • 如何防止野指针的产生
    • 指针定义时及时初始化
      • 在初始化之前,p都是野指针
    • 绝不引用已被会回收的内存
    • 确认所申请的内存边界

空指针

很多情况下,我们不可避免地会遇到野指针,比如刚定义的指针无法立即为其分配一块恰当的内存,又或者指针所指向的内存被释放了等等。一般的做法就是将这些危险的野指针指向一块确定的内存,比如零地址内存(通用类型地址)。

空指针保存了零地址的指针,指向零地址,在LInux中,从0x0000 0000 一直到0x0804 8000 之间,内存被成为不可访问内存,如果程序访问了这段内存,计算机程序会报错(段错误Segmentation fault)

``

通用类型地址(void *)

可以接受任何类型的地址,也可也传递任何类型的地址

只有void *p 没有void a

二级指针

储其他指针地址的指针就是二级指针

int a = 77;
int *p = &a;
int **q = &p;
  • 在上述代码中
    • q == &p q存储的值是p的地址
    • *q == p == &a 解引用q就是通过p的地址取p的值,拿到a的地址(p的值就是a的地址)
此作者没有提供个人介绍。
最后更新于 2026-01-15