基础知识点 | 0920_指针,数组指针,指针数组的总结及题目
入门知识点:
- 指针和指针变量是两个不同的概念,但要注意的是,通常我们叙述时会把指针变量简称为指针。
- 指针就是地址,地址就是指针,它是一个形无符号整型的一个整数。它的大小取决于系统是16,32 还是64位的 16/8=2byte,32/8=4byte,64/8=8byte.
- 指针变量其实是一个变量,只不过其存放的内容为地址,如
int* p,这个p是指针类型,它的值存的是地址
基础知识点:
- 二维数组,数组指针,指针数组
//初始化二维数组a
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
//指针
int *(p1[5]); //指针数组,可以去掉括号直接写作 int *p1[5];
int (*p2)[5]; //二维数组指针,不能去掉括号
- 内存中a的分布:

- 二维指针的指向方式如图:

-
指向二维数组的指针:
-
[]的优先级高于*,所以int (*p)[4]和int *p[4]不同。- 前者中,p是一个指针,指向一个数组,且数组的类型是int [4],
p+1会使得指针移动16字节,指向a数组的下一行。 - 后者中,p是一个指针数组,内部存放4个指针,每个值是一个指针,指向一块地址。
- 前者中,p是一个指针,指向一个数组,且数组的类型是int [4],
/*
* Sep.20 2021 by july_iet
*
* 内存中数组a的存放方式是一维的:
* a[0] - a[1] - a[2] - a[3] - a[4] - a[5] - a[6] - a[7] - a[8] - a[9] - a[10] - a[11]
*
* 二维指针的指向方式:
* a(p) -> a[0](p) -> a[0][0] - a[0][1] - a[0][2] - a[0][3]
* -> a[1](p+1) -> a[1][0] - a[1][1] - a[1][2] - a[1][3]
* -> a[2](p+2) -> a[2][0] - a[2][1] - a[2][2] - a[2][3]
* -> a[3](p+3) -> a[3][0] - a[3][1] - a[3][2] - a[3][3]
*/
#include <iostream>
using namespace std;
int main() {
//初始化
int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int(*p)[4] = a;
//part 1 :对 a 和 p 的操作是一样的
cout << "part 1 : " << endl;
cout << "整个数组的地址a : " << a << endl;
cout << "第0行的地址*a : " << *a << endl;
cout << "a[0][0] 的值 **a :" << **a << endl << endl;
cout << "整个数组的地址p : " << p << endl;
cout << "第0行的地址*p : " << *p << endl;
cout << "a[0][0] 的值 **p :" << **p << endl << endl;
//part 1 输出:
part 1 :
整个数组的地址a : 001AF8DC
第0行的地址*a : 001AF8DC
a[0][0] 的值 **a :0
整个数组的地址p : 001AF8DC
第0行的地址*p : 001AF8DC
a[0][0] 的值 **p :0
//part 2 : 取行地址的方式
cout << "part 2 : " << endl;
cout << "第1行的地址 a[1] : " << a[1] << endl;
cout << "第1行的地址 *(p+1) : " << *(p+1) << endl << endl;
//part 2 输出:
part 2 :
第1行的地址 a[1] : 001AF8EC
第1行的地址 *(p+1) : 001AF8EC
//part 3 : 奇妙尝试1 - 易混淆点
cout << "part 3 : " << endl;
cout << "a[1]第1行 的地址 *(a+1) : " << *(a+1) << endl;
cout << "a[0][1] 的地址 *a + 1 : " << *a + 1 << endl << endl;
//part 3 输出:
part 3 :
a[1]第1行 的地址 *(a+1) : 001AF8EC
a[0][1] 的地址 *a + 1 : 001AF8E0
//part 4 : 奇妙尝试2 - 一个实例
cout << "part 4 : " << endl;
cout << "a[1][1]+2 的值 *(*a+1) + 2 :" << *(*a+1) + 2 << endl;
cout << "a[1][2] 的值 (*(a+1))[2] :" << (*(a+1))[2] << endl;
//part 4 输出:
part 4 :
a[1][1]+2 的值 *(*a+1) + 2 :3
a[1][2] 的值 (*(a+1))[2] :6
return 0;
}
- 取值基础题:
-
p--- 指向数组的开头a[0],指向第一行 -
*(p+1)--- 相当于a[1],指向的内容是二维数组中对应第二行的数据 -
*(p+1)+1--- 相当于&a[1][1],*(p+1)放在表达式中表示第二行数据的首地址,可以直接做+j操作,得到该行的第j位的地址 -
*(*(p+1)+1)--- 相当于a[1][1],是该行的第j位的值
- 指针进阶题:

解答:
前者是指针数组,得到数组开头的值是"A4_Pi",后者是指向二维数组的指针,取数组开头的值仍是“A4_Pi”

解答:
B选项,b[i]取第i行的地址,+j后等同于&a[i][j],再利用*解引用;
C选项,*b取第0行的地址b[0],+i等同于b[0][i]的地址,解引用后得到b[0][i]的值,再对该值做+j操作,相当于b[1][1]+2;
D选项,*(b+i)拿到第i行的地址b[i],通过[]取b[i][j]的值

解答:
需要注意的点在于strlen(x)包含'/0',所以结果为5;
而语句*x = x[n]将'/0'赋值给了y[0];

浙公网安备 33010602011771号