基础知识点 | 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个指针,每个值是一个指针,指向一块地址。
/*
* 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 + 1001AF8E0

    //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) + 23
    a[1][2]   的值 (*(a+1))[2] :6

    return 0;
}


  • 取值基础题:
  1. p --- 指向数组的开头 a[0],指向第一行

  2. *(p+1) --- 相当于a[1],指向的内容是二维数组中对应第二行的数据

  3. *(p+1)+1 --- 相当于&a[1][1]*(p+1)放在表达式中表示第二行数据的首地址,可以直接做+j操作,得到该行的第j位的地址

  4. *(*(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]

posted @   不是勇士  阅读(339)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示