阅读 56

C++指针理解

整形数组指针

void int__array_pointer_test() {
    int array[] = {1, 2, 3, 4, 5};
    int *p = array;
    int **pr = &p;
    for (int i = 0; i < 5; ++i) {
        cout << "array[" << i << "] address in memory is " << &array[i] << endl;
    }
    //输出数组名,输出的是第一个元素的地址
    cout << "array = " << array << endl;
    //输出指向整形数组的指针,输出的还是第一个元素的地址
    cout << "p = " << p << endl;
    //对指向整形数组的指针做解引用操作,输出的是第一个元素的值
    cout << "*p = " << *p << endl;
    //输出指向整形数组的指针的指针,输出的是存储着数组第一个元素地址的内存地址
    cout << "pr = " << pr << endl;
    //输出对pr做一次解引用操作的结果,也就是第一个元素的地址
    cout << "*pr = " << *pr << endl;
    //输出对pr做两次解引用操作的结果,也就是第一个元素的值
    cout << "**pr = " << **pr << endl;
    /**
     * 
     */
}
}
复制代码

运行结果:

array[0] address in memory is 0x28ff14
array[1] address in memory is 0x28ff18
array[2] address in memory is 0x28ff1c
array[3] address in memory is 0x28ff20
array[4] address in memory is 0x28ff24
array = 0x28ff14
p = 0x28ff14
*p = 1
pr = 0x28ff10
*pr = 0x28ff14
**pr = 1
复制代码

总结如下: 1. array[0] = *p = **pr; 2. array = p = *pr 3. pr存放的是p的地址,p存放的是array/array[0]的地址

字符数组

void char_array_pointer_test(){
    char array[] = {"Digist"};
    char *p = array;
    char **pr = &p;
    for (int i = 0; i < 5; ++i) {
        cout << "array[" << i << "] address in memory is " << &array[i] << endl;
    }
    //输出数组名,输出的是整个数组的值
    cout << "array = " << array << endl;
    //输出指向字符数组的指针,输出的也是整个数组的值
    cout << "p = " << p << endl;
    //对字符数组的指针做解引用操作,输出的是第一个元素的值
    cout << "*p = " << *p << endl;
    //输出指向字符数组指针的指针,输出的是存储第一个元素地址的内存地址
    cout << "pr = " << pr << endl;
    //输出对指向字符数组的指针做一次解引用操作的结果,输出的是整个数组的值
    cout << "*pr = " << *pr << endl;
    //输出对指向字符数组的指针做两次解引用操作的结果,输出的是第一个元素的值
    cout << "**pr = " << **pr << endl;
}
}
复制代码

运行结果:

array[0] address in memory is Digist
array[1] address in memory is igist
array[2] address in memory is gist
array[3] address in memory is ist
array[4] address in memory is st
array = Digist
p = Digist
*p = D
pr = 0x28ff1c
*pr = Digist
**pr = D

复制代码

总结:发现字符数组在输出的时候和整形数组有区别,本以为和整形数组一样应该输出地址的地方基本都输出的是整个数组的值,而希望可以看到地址的话需要对指针进行强转,转成(int *)或者(void *)

修正结果

void char_array_pointer_test2(){
    char array[] = {"Digist"};
    char *p = array;
    char **pr = &p;
    for (int i = 0; i < 5; ++i) {
        cout << "array[" << i << "] address in memory is " << (int *)&array[i] << endl;
    }
    cout << "array = " << (void *)array << endl;
    cout << "p = " << (int *)p << endl;
    cout << "*p = " << *p << endl;
    cout << "&p = " << &p << endl;
    cout << "pr = " << pr << endl;
    cout << "*pr = " << *pr << endl;
    cout << "**pr = " << **pr << endl;
}
复制代码

运行结果:

array[0] address in memory is 0x28ff21
array[1] address in memory is 0x28ff22
array[2] address in memory is 0x28ff23
array[3] address in memory is 0x28ff24
array[4] address in memory is 0x28ff25
array = 0x28ff21
p = 0x28ff21
*p = D
&p = 0x28ff1c
pr = 0x28ff1c
*pr = Digist
**pr = D

复制代码

总结如下:

  1. 直接输出字符数组变量,输出的是整个数组的值,要输出其地址,需要将变量名进行强转
  2. 一个指向字符数组的指针,输出这个指针遍历,输出也是这个字符数组的值,要得到其存储的地址需要进行强转
  3. &array[0] = array = p = *pr = 字符数组的值; (int *)array = (void *)p = 字符数组的内存地址;array[0] = *p = **pr = 首元素的值

结构体

struct my_year {
    int year;
};

void test_point_to_struct_pointer() {
    my_year s1, s2, s3;
    s1.year = 1998;
    s2.year = 2002;
    s3.year = 2004;
    my_year *pa = &s2;
    pa->year = 1999;
    my_year trio[3]{{1000},
                    {2000},
                    {3000}};
    my_year *pr = trio;
    my_year **ptr = &pr;
    for (int i = 0; i < 3; ++i) {
        cout << "trio[" << i << "] address in memory is " << &trio[i] << endl;
    }
    cout << "trio = " << trio << endl;
    cout << "pr = " << pr << endl;
    //此处会崩溃
    //cout << "*pr = " << *pr << endl;
    cout << "ptr = " << ptr << endl;
    cout << "*ptr = " << *ptr << endl;
    //cout << "**ptr = " << **ptr << endl;

    for (int i = 0; i < 3; ++i) {
        cout << (pr + i)->year << endl;
    }
    const my_year *arp[3] = {&s1, &s2, &s3};
    cout << "&s1 = " << &s1 << endl;
    cout << "&s2 = " << &s2 << endl;
    cout << "&s3 = " << &s3 << endl;

    const my_year **ppb = arp;
    cout << "ppb = " << ppb << endl;
    cout << "arp = " << arp << endl;
    cout << "arp[0] = " << arp[0] << endl;
    cout << "&arp[0] = " << &arp[0] << endl;
    cout << "*ppb = " << *ppb << endl;
    cout << "&ppb = " << &ppb << endl;
//    cout << (void *)arp << end;
}
复制代码

运行结果:

trio[0] address in memory is 0x28ff08
trio[1] address in memory is 0x28ff0c
trio[2] address in memory is 0x28ff10
trio = 0x28ff08
pr = 0x28ff08
ptr = 0x28ff04
*ptr = 0x28ff08
1000
2000
3000
&s1 = 0x28ff1c
&s2 = 0x28ff18
&s3 = 0x28ff14
ppb = 0x28fef8
arp = 0x28fef8
arp[0] = 0x28ff1c
&arp[0] = 0x28fef8
*ppb = 0x28ff1c
&ppb = 0x28fef4
复制代码

总结:结构体数组中很多和整形数组相同 trio = &trio[0] = pr = *ptr arp是一个指针数组,arp = ppb = &arp[0],arp[0] = *ppb

指针数组和数组指针

指针数组首先它是一个数组,而数组指针首先是一个指针 运算符的先后顺序是:()>[]>* char *p[4]表示的是指针数组 char (*p)[4]表示的是数组指针 平时这样写

char array[4];
char *p;
p = array;
复制代码
文章分类
阅读
文章标签