指针的进阶(二)

简介: 指针的进阶(二)

数组指针

3.1 数组指针的定义

数组指针落脚点在最后两个字,所以数组指针就是一个指针。

字符指针,指向字符的指针;

整形指针,指向整形的指针;

数组指针,指向数组的指针。

1. #include <stdio.h>
2. int main()
3. {
4.  int a = 3;
5.  int* p = &a;
6.  int* arr[10];//指针数组 arr和[10]结合,arr是一个数组
7.  int* arr[10];//指针数组 arr和[10]结合
8.  int(*arr)[10];//数组指针 ,arr和*结合,arr是一个指针,数组指针,int类型  数组指针,指向数组的指针
9.  return 0;
10. }

int (*p)[10];

//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

//这里要注意:[]的优先级要高于*号的,所以必须加上()来保证p先和*结合

3.2 &数组名VS数组名

int arr[10];

arr 和 &arr 分别是啥?我们知道arr是数组名,数组名表示数组首元素的地址。那&arr数组名到底是啥?

代码1展示:

1. #include <stdio.h>
2. int main()
3. {
4.  int arr[10];
5.  printf("%p\n", arr);
6.  printf("%p\n", &arr);
7.  return 0;
8. }

代码2展示:

1. #include <stdio.h>
2. int main()
3. {
4.  int arr[10];
5.  printf("%p\n", arr);
6.  printf("%p\n", &arr);
7.  printf("%p\n", arr + 1);
8.  printf("%p\n", &arr + 1);
9.  return 0;
10. }

比较代码1和代码2:根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。

实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下)

arr是数组首元素(第一个元素)地址,如果存放在一个指针变量里,就是int*类型   arr+1 是第二个元素的地址 ,如果存放在一个指针变量里,就是整形指针类型

本例中 &arr 的类型是: int(*)[10] ,  是一种数组指针类型(int a;去掉变量就是类型)

数组的指针存放起来,就是放在数组指针里。

数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.

(*p)说明是一个指针,(*p)[10]说明是一个数组,指向的数组里的元素是什么类型,int 类型,  数组的类型是int [10]

int* a;*说明a是一个指针。

3.3 数组指针的使用

数组指针指向的是数组,那数组指针中存放的应该是数组的地址

#include <stdio.h>

int main()

{

   int arr[5];

   int(*p)[5] = &arr;p的类型是int(*)[5]

   int* paa[3];//指针数组,也是一个数组,数组里面的元素是int*类型

   int* (*pp)[3] = &paa;//数组指针,pp的类型是int*(*)[3]

   return 0;

}

指针数组的用途:

打印数组元素地址

代码1展示:

1. #include <stdio.h>
2. int main()
3. {
4.  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
5.  int* p = arr;
6.  int i = 0;
7.  for (i = 0; i < 10; i++)
8.  {
9.    printf("%d ", *(p+i));
10.   }
11.   return 0;
12. }

打印结果:1 2 3 4 5 6 7 8 9 10  

代码2展示:

1. #include <stdio.h>
2. int main()
3. {
4.  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
5.  int(*p)[10] = &arr;
6.  int i = 0;
7.  for (i = 0; i < 10; i++)
8.  {
9.    printf("%d ", *((*p) + i));p是&arr,*p是arr。
10.   }
11.   return 0;
12. }

打印结果:1 2 3 4 5 6 7 8 9 10

代码2这种方法不建议,数组指针我们一般用在二维数组中。

打印二维数组:

代码1展示:

1. #include <stdio.h>
2. void print(int arr[3][5], int a, int b)
3. {
4.  int i = 0;
5.  int j = 0;
6.  for (i = 0; i < a; i++)
7.  {
8.    for (j = 0; j < b; j++)
9.    {
10.       printf("%d ", arr[i][j]);
11.     }
12.     printf("\n");
13.   }
14. }
15. int main()
16. {
17.   int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} };
18.   print(arr, 3, 5);
19.   return 0;
20. }

打印结果:

代码2展示:

二维数组在传参的时候,数组名也代表首元素地址,这个首元素指的是 第一行 ;首元素地址指的是第一行的地址

1. #include <stdio.h>
2. void print(int(*p)[5], int a, int b)//p+1就是第二行的地址,p+2就是第三行的地址
3. {
4.  int i = 0;
5.  int j = 0;
6.  for (i = 0; i < a; i++)
7.  {
8.    for (j = 0; j < b; j++)
9.    {
10.       printf("%d ", *(*(p + i) + j));// *(p+i)拿到的是第i行的地址,相当于第i行的数组名,也就是第i行的首元素地址,也是第一个元素的地址
11.     }
12.     printf("\n");
13.   }
14. }
15. int main()
16. {
17.   int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15} };
18.   print(arr, 3, 5);
19.   return 0;
20. }

上图中的二维数组的首元素地址是 第一行的地址,传到函数里是int(*p)[5],

重点理解:

 上述代码,p代表的是&第一行整个数组,p+i代表的是&第i行整个数组,*(p+i)代表的是第i行的数组名。数组首元素地址,数组首元素地址+i,指的是第i个元素。

1. #include <stdio.h>
2. int main()
3. {
4.  int arr[5];//arr是一个整形数组,有5个元素,每一个元素都是int类型
5.  int* parr1[10];//parr1是一个数组,数组有10个元素,每一个元素是int*类型
6.  int(*parr2)[10];//parr2和*结合,说明parr2是一个指针,该指针指向一个数组,所以是一个数组指针
7.  int(*parr3[10])[5];//把arr3[10],看做一个整体,指向数组为[5]的int的指针,这个指针是[10].
8. //parr3和[]结合。说明parr3是一个数组,数组是10个元素,数组每一个元素的类型是int(*)[5],该类型的指针指向的数组有5个int类型的元素。    数组的类型是int*[5],也就是这个指针是数组,一共10个元素,每一个元素(指针)指向的是int[5]   
9. return 0;
10. }

理解: parr3的类型是,int(*)[5],可以看做 int(*)[5] parr3,此时就是一个数组指针,但是上图是一个数组,那么就是10个数组指针放在了一起,是parr3[10]。

相关文章
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
5月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
5月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
5月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
5月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
47 4
|
5月前
指针进阶(3)
指针进阶(3)
41 1
|
5月前
|
C++
指针进阶(1)
指针进阶(1)
43 1
|
5月前
|
存储 安全 编译器
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
42 2
|
5月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
49 0