指针和引用(3)指针数组和数组指针

简介: 1.知识点1.1指针数组——存放指针的数组(1)指针数组本质上是一个数组,指针是数组中的内容,表示数组中的每个元素都是指针,因此指针数组就是存放指针的数组。下面是指针数组的用法:1 int a = 10, b = 20;2 int *p[3];3 p[0] = &a;4 p[2] = &b;(2)指针数组的定义可以抽象为:指向变量类型 * 数组名称[数组长度]。

1.知识点

1.1指针数组——存放指针的数组

(1)指针数组本质上是一个数组,指针是数组中的内容,表示数组中的每个元素都是指针,因此指针数组就是存放指针的数组。下面是指针数组的用法:

1 int a = 10, b = 20;
2 int *p[3];
3 p[0] = &a;
4 p[2] = &b;

(2)指针数组的定义可以抽象为:指向变量类型 * 数组名称[数组长度]。

(3)[]的优先级高于*,所以[]与p先结合,说明p是一个数组,长度为3,其数组元素的类型是int *。

1.2数组指针——指向数组的指针

(1)数组指针本质上是一个指针,数组是指针指向的类型,表示指针指向一个数组,因此数组指针就是指向数组的指针。下面是数组指针的用法:

1 int a[3] = { 1,2,3 };
2 int (*p)[3];
3 p = &a;

(2)数组指针的定义可以抽象为:数组元素类型 (* 指针名称)[数组长度]。

(3)()使得*与p先结合,所以p是一个指针,盖掉(*p)剩下的就是指针指向的内容了即int[3]。

(4)数组指针指向整个数组a(取地址&a),而非数组a的首元素(取地址a),虽然数组a和数组a中首元素的地址相同。

2.面试题

2.1简述数组指针与二维数组的区别

请写出下面程序的输出结果(假设数组a的地址&a为0x001DF720)

 1 int main(int argc, char *argv[]) {
 2     //数组指针和二维数组的区别
 3     int a[2][5] = { {1,2,3,4,5},{6,7,8,9,10} };
 4     int(*p)[5] = a;
 5     cout << p << endl;
 6     cout << p + 1 << endl;
 7 
 8     cout << *p << endl;
 9     cout << *(p + 1) << endl;
10     cout << *p + 1 << endl;
11 
12     cout << **p << endl;
13     cout << **(p + 1) << endl;
14     cout << *(*p + 1) << endl;
15 
16     getchar();
17     return 0;
18 }

知识点提示:(1)数组名始终等价于数组首元素的地址:a<=>&a[0]。

(2)解引用的次数等于数组的维度时,才能得到数组的元素值,如二维数组必须经过两次解引用才能得到数组的元素值。

(3)数组首元素地址和数组的地址虽然位置一样,但是二者完全不是一回事(通过解引用来理解),数组首元素地址&a[0]解引用之后为*(&a[0])=a[0],是首元素的值;而数组地址&a解引用之后为*(&a)=a=&a[0];通过以上说明,数组地址一次解引用之后得到数组首元素的地址,再解引用之后得到首元素的值(在一维数组的情况下)。

(4)二维数组a[n][m],可以把a[n]看成是内层[m]的数组名。

按照以上的知识和规则认真分析可以得出如下答案:

 1 //数组a的地址&a为0x001DF720
 2  int main(int argc, char *argv[]) {
 3      int a[2][5] = { {1,2,3,4,5},{6,7,8,9,10} };
 4      int(*p)[5] = a;//a==&a[0],左右类型相同,p指向一个元素为5的一维数组
 5      cout << p << endl;//两次解引用是地址,p=&a[0],0x001DF720
 6      cout << p + 1 << endl;//两次解引用是地址,p+1=&a[1]=0x001DF720+4*5=0x001DF734
 7   
 8      cout << *p << endl;//一次解引用是地址,*p=a[0]=&a[0][0],0x001DF720
 9      cout << *(p + 1) << endl;//一次解引用是地址,*(p+1)=a[1]=&a[1][0],0x001DF734
10      cout << *p + 1 << endl;//一次解引用是地址,*p+1=&a[0][1]=0x001DF724
11  
12      cout << **p << endl;//二次解引用是元素值,**p=a[0][0]=1
13      cout << **(p + 1) << endl;//二次解引用是元素值,**(p+1)=a[1][0]=6
14      cout << *(*p + 1) << endl;//二次解引用是元素值,*(*p+1)=a[0][1]=2
15  
16      getchar();
17      return 0;
18  }

2.2简述数组地址和数组首地址的区别

指出下面程序中的错误:

1 int main(int argc, char *argv[]) {
2     int b[6] = { 1,2,3,4,5,6 };
3     int *p = &b;  //左右类型不匹配
4     cout << p << endl;
5 
6     getchar();
7     return 0;
8 }

知识点:数组首元素地址和数组的地址虽然位置一样,但是二者完全不是一回事(通过解引用来理解),数组首元素地址&a[0]解引用之后为*(&a[0])=a[0],是首元素的值;而数组地址&a解引用之后为*(&a)=a=&a[0];通过以上说明,数组地址一次解引用之后得到数组首元素的地址,再解引用之后得到首元素的值(在一维数组的情况下)。

修改方式以下二选其一:

1 //方式一
2 int (*p)[6]=&b;
3 //方式二
4 int *p=b;//或者:int *p=&b[0];

2.3简述指针数组与指向指针的指针的区别

写出指针数组str中四个指针元素的值。

由于题目有问题,未正确解答,故略。

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