【 C/C++ 】指针小节

【 数组与指针 】

1. 指向整型变量的指针

指针变量,表示指向某变量地址的变量,即内存所指向变量的地址。Eg. int a = 1; int *p = &a;   => *p = 1;

p和*p的值都是可以改变的(在没有const修饰的情况下):

p的值该表表示p指向了其他元素,而*p的值改变,表示*p指向的元素的值改变(要先给p赋值才可以给*p赋值,否则p指向未知的地址)

                  【 C/C++ 】指针小节

 

2. 指向一维整型数组的指针

          对于一个数组而言,数组名可看做指向数组起始位置的指针:      【 C/C++ 】指针小节

 

 

 

         假设我们有一组数组, int a[5] = {1,2,3,4,5}, 我们有:

         a == &a[0]; a+i == &a[i], *(a+i) == a[i]

         由此可以把a赋值给一个整型指针,并通过该指针访问数组:

         int *p = a; =>

         p+i == a+i == &a[i] => *(p+i) == a[i]

         可以通过p++来遍历整个数组,效率会比数组名遍历高。

 

3. 指向多维整形数组的指针

对于多维数组,我们可以通过下图来理解;假设有二维数组: int a[2][3] = {{1,2,3}, {4,5,6}};

一维数组数组名可看做指向该数组第一个元素的起始地址;

二维数组数组名可看做指向该数组行维度里的第一个元素(即第一行)的起始地址;

 

【 C/C++ 】指针小节            a: &a[0] 第0行起始位置;

            a+i: &a[i] 第i行起始位置;

    *(a+i): a[i] 第i行第0个元素起始位置;

    *(a+i)+j: a[i]+j 第i行第j个元素起始位置;

    *(*(a+i)+j): a[i][j] 第i行第j个元素起始位置

 

 

可以定义一个指向该多维数组某行的指针:int (*p)[3] = a+i; p指向第i行起始位置, p++操作可指向数组下一行起始位置,

*p表示a[i], *p+j, 表示第i行第j个元素起始位置

注意需要括号 (*p), 表示是一个指向有3个int元素数组的指针;

若写成 int *p[3], 则表示有3个元素的整型指针数组;

 

4. 字符数组

字符数组是比较特殊的一类数组,可以用来表示一个字符串

char str[] = {"I love C++"};

也可定义为: char *str2 = "I love C++"; (*str2 == str[0] == 'I', str2 == str == "I love C++")

 

如果是定义一个二维字符数组,一般可用一个指针数组定义

【 C/C++ 】指针小节

 

          

char *str[] = { {"I"}, {"love"}, {"C++"}};

str[0] = "I", str[1] = "love", str[2] = "C++"

之所以用指针数组来定义二维字符数组,因为一般情况下这样的数组列数不一致无法确定长度。

 

 

 

5. 指向指针的指针

指向指针的指针,常用来定义一个指针数组:

int **p1 => int *p2[ ]; (p2是一个指针数组数组名,指向该数组第一个指针的起始地址)

char **str1 => char *str2[ ];

=> p1 = p2: p1+i == p2+i == &p2[i] (数组中第i个指针的地址); *(p1+i) == *(p2+i) == p2[i](第i个指针,即第i个指针指向的元素地址);

  **(p1+i) == **(p2+i) == *p2[i] (数组中第i个指针指向的数值)

=> str1 = str2: str1+i == str2+i == &(str2[i]) (数组中第i个指针的地址); *(str1+i) == *(str2+i)==str2[i](第i个指针,即第i个字符串);

  **(str1+i) == **(str2+i) == *str2[i] (数组中第i个指针指向的字符串的第一个字符)

【区分】

二维数组数组名 => 对应指向二维数组某行的指针; int a1[3][4] => int (*p1)[4]

一维指针数组名 => 对应指向指针的指针; int *a2[4] => int **p2

指针值 对应数组值 表示
p1 a1/&a1[0] 第0行起始地址
p2 a2/&a1[0] 第0个指针起始地址
p1+i a1+i/&a1[i] 第i行起始地址
p2+i a2+i/&a1[i] 第i个指针起始地址
*(p1+i) *(a1+i)/a1[i] 第i行第0个元素起始地址
*(p2+i) *(a2+i)/a2[i]

第i个指针值,第i个指针指向的元素的起始地址

若为字符类型,也可表示第i个字符串

*(p1+i)+j *(a1+i)+j/&a1[i][j] 第i行第j个元素起始地址
*(p2+i)+j NA NA
*(*(p1+i)+j) *(*(a1+i)+j)/a[i][j] 第i行第j个元素的值
*(*(p2+i)+j) NA  
**p2 **a2/*a2[0] 第0个指针指向的元素的值
**(p2+i) **(a2+i)/*a2[i] 第i个指针指向的元素的值
**p1/**(p1+i) NA  

代码示例:

#include <iostream>

using namespace std;

int main() {
    int a1[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
    int *a2[4];
    for(int i = 0; i < 4; ++i) a2[i] = &a1[0][i];
    int (*p1)[4] = a1;
    int **p2 = a2;
    cout << *(*(p1+1)+2) << ", " << a1[1][2] << endl;
    //第1行第2列元素的值
    cout << **(p2+1) << ", " << *a2[1] << endl;
    //第1个指针指向的元素的值
    char *str[] = {"Hello", "World", "I", "Love", "C++"};
    char **sp = str;
    cout << *(sp+1) << ", " << str[1] << endl;
    //第1个字符串
    cout << **(sp+1) << ", " << *str[1] << endl;
    //第1个字符串的第0个字符
}

输出结果:

7, 7
2, 2
World, World
W, W

 

 【 指向函数的指针 】

int (*p)(int, int): 表示指针p是一个可以指向函数原型为 int func(int a, int b)一类的函数,为简化代码以及提高代码可维护性。

当给p赋值: p = func, p指向函数func的入口处;可通过p来调用指针func

#include <iostream>

using namespace std;

int minNum(int a, int b) {
    return (a < b)?a:b;
}

int maxNum(int a, int b) {
    return (a > b)?a:b;
}

int main() {
    int x = 3, y = 5;
    int (*p)(int, int);
    p = maxNum;
    cout << "The bigger number of " << x << " and " << y << " is: " << p(x, y) << endl;
    p = minNum;
    cout << "The smaller number of " << x << " and " << y << " is: " << p(x, y) << endl;
}

输出:

The bigger number of 3 and 5 is: 5
The smaller number of 3 and 5 is: 3

 

原文链接: https://www.cnblogs.com/xiyang2020/p/12763645.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    【 C/C++ 】指针小节

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/344091

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午2:28
下一篇 2023年3月2日 上午2:29

相关推荐