【进阶指针一】字符数组&数组指针&指针数组(下)

简介: 【进阶指针一】字符数组&数组指针&指针数组

4. 数组指针

int main()
{
  //整型指针-指向整型的指针-存放整型变量的地址
  int a = 10;
  int* pa = &a;
  //整型指针-指向字符的指针-存放字符变量的地址
  char ch = 'w';
  char* pc = &ch;
  //数组指针-指向数组的地址,存放数组变量的地址
  int arr[5] = { 1,2,3,4,5 };
  int(*p)[5]=&arr;//注意这个5不能省略,因为这个5是指针指向的那个数组的类型
}

cc12704fb3664af08783eca1ae8fe708.png一个指针只能存放一个地址,只不过这个地址是整个数组的地址

4-1 区分取地址数组名和数组名(老生常谈了

3f4225e8e5a64f519ba33e6fe400f5fc.png


4-1-1 sizeof(数组名):求的是该类型所定义的变量在内存中所占空间的大小,单位是字节。

int main()
{
  int arr1[5] = { 1,2,3,4,5 };
  printf("%d\n", sizeof(arr1));//32位平台下:20字节   64位平台下:20字节//类型;int[5]数组
  printf("%d\n", sizeof(arr1+0));//32位平台下:4字节   64位平台下:8字节//已经不是单独的sizeof(数组名)//类型:int*指针
  printf("%d\n", sizeof(arr1[0]));//32位平台下:4字节   64位平台下:8字节//类型:int*指针
  return 0;
}

4-1-2  &数组名,在没有+-整数时虽然地址是相同的,但是意义不同。


2194fe8667ab427fad2953719d6c1dfc.png

4-2 辨析数组指针和指针数组

图图我就省略喽!😁😁😁

int main()
{
  //我们知道:去掉变量名剩下的部分就是变量所属的类型
  //(这里可以通过调试得以验证以下猜想)
  //整型数组,数组类型为int [5],从左往右念就是整型数组
  //特别注意:数组索引中的元素个数5也是类型的一部分
  //所以int [4]和int [5]所属的是不同的类型
  int arr[5] = { 1,2,3,4,5 };
  //p1先和方块5(也就是[5])结合,所以整体来看p1是一个数组
  //既然是数组我们关心的就是数组呢存放的是什么?
  //数组内有五个元素,每个元素的类型是int* 类型
  //所以变量p1的类型为int* [5],从左往右念就是指针数组
  int* p1[5] = { arr,&arr[1] ,&arr[2], &arr[3], &arr[4] };
  //p2先和*结合,所以整体来看p2是一个指针
  //既然是指针,我们关心的就是指针指向的是什么?
  //指针指向的是一个数组,数组内有五个元素,每个元素时int类型
  //所以变量p2的类型为int[5]*,从左往右念就是数组指针
  int(*p2)[5] = &arr;
  return 0;
}

abd6aac032f94b46b53fc75cb6ad39ae.png


4-3 学会了?来看一个小测试题


image.png

387d97cda0fa40719a48af31b5f7602b.png

4-4  来看一个脱裤子放屁的代码【看一看数组指针的使用】

void Print1(int arr[], int sz)
{
  printf("Print1:\n");
  for (int i = 0; i < sz; i++)
  {
    printf("%d\t", arr[i]);
  }
}
void Print2(int* arr, int sz)
{
  printf("Print2:\n");
  for (int i = 0; i < sz; i++)
  {
    printf("%d\t", arr[i]);
  }
}
void Print3(int(*p)[5],int sz)
{
  printf("Print3:\n");
  for (int i = 0; i < sz; i++)
  {
     printf("%d\t", *((*p)+i));
    //printf("%d\t", (*p)[i]);
  }
}
int main()
{
  int arr[5] = { 1,2,3,4,5 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  //写一个函数打印数组内容
  //测试1:
  Print1(arr, sz);
  printf("\n");
  //测试2:
  Print2(arr, sz);
  printf("\n");
  //测试3:
  Print3(&arr,sz);
  return 0;
}

73a0a9c0dd6340d6b1418d6a34ea159c.png

efb4b61475f2440b9cac22d7b2740ec8.png

4-5 这才是数组指针的正确使用方法捏【数组指针模拟打印二维数组】


指针数组虽然可以int(*p)[3]=&arr;其中arr是一个一维数组,但是这样太鸡肋了,


还不如直接int*p arr;


指针数组真正的使用场景是留给二维数组传数组名时,形参用指针数组接收。  

void Print1(int arr[3][5], int row, int col)
{
  printf("Print1:\n");
  for (int i = 0; i < row; i++)
  {
    for (int j = 0; j < col; j++)
    {
      printf("%d\t", arr[i][j]);
    }
    printf("\n");
  }
}
void Print2(int(*p)[5], int row, int col)
{
  printf("Print2:\n");
  for (int i = 0; i < row; i++)
  {
    for (int j = 0; j < col; j++)
    {
      printf("%d\t", (* (p + i))[j]);
      //printf("%d\t", *(*(p+i)+j));
            //printf("%d\t",p[i][j]);
      //p+i是第i行,也就是第i行整个数组的地址
      //*(p+i)也就是对整个数组的地址解引用,就是第i行的数组名,也就是第i行首元素的地址
      //*(p+i)+j就是第i行第j列元素的地址
      //*(*(p+i)+j)也就是对第i行第j列元素的地址解引用,就是第i行第j列的元素
    }
    printf("\n");
  }
}
int main()
{
  int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
  //测试1:
  Print1(arr, 3, 5);
  printf("\n");
  //测试2:
  Print2(arr, 3, 5);
  printf("\n");
  return 0;
}

43fa6e3686a1438a8356d16b51c279c1.png

上面目前讲的基本还是数组指针指向的是一个一维数组


其实数组指针还是可以指向一个二维数组:


int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };


int(*p)[3][5]=&arr;


完结,撒花,等等,要不来一个小测试?


5 测试题和规律总结

测验1:

如果int(*arr[3])[5];

问题:怎么理解这个代码?

答案:数组指针数组

3c2a32ce59524b799c48bbdb5aac6c7e.png


d844daae6b9f4ef69717702df763434d.png

测验2:那么指针数组指针?


0d2bf3ca84f24099a210614d2e78731d.png

我总结的一点小规律


如果光要给上面这个东西命名的话,只用关注*和[]的出现次序排列就可以了

比如;数组指针数组:[]*[]

          指针数组指针*[]*  

然后再把[]存的内容和*指向的东西往里面填进去就可以了


目录
相关文章
|
1月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
37 3
|
24天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
28天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
28天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
28天前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
53 4
|
1月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
48 2
|
1月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
39 1
|
2月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
2月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。