C++ 复合数据类型:指针

文章目录

  • 指针
    • 用法
    • 无效指针
    • 空指针
    • void *ptr
    • 指向指针的指针
    • 指向常量的指针
    • 指针常量
    • 指针和数组
      • 指针数组和数组指针

指针

计算机中的数据都存在内存中,访问内存的最小单元是“字节”,所有数据,就保存在内存中具有连续编号的一串字节中。
C++ 复合数据类型:指针_第1张图片
指针顾名思义就是指向另一种数据类型的复合类型。指针是C/C++中保存另一个数据对象在内存中的“地址”。通过指针可以访问到指向的那个数据对象,所以这是一种间接访问对象的方法。
指针的定义语法形式:类型* 指针变量;
类型是指针指向的对象的类型。
例如:以下 int 类型占4个字节,char占1个字节,指针占8个字节,指针里存的是a的地址:
00 00 00 34 F7 EF F8 88
C++ 复合数据类型:指针_第2张图片

#include

using namespace std;

int main()
{
    //定义指针
    int *p1;
    long *p2;
    long long *p3;

    cout << "p1长度:" << sizeof(p1) << endl;
    cout << "p2长度:" << sizeof(p2) << endl;
    cout << "p3长度" << sizeof(p3) << endl;
    //指针存放的都是地址,因此它的长度只与系统有关,而不是与类型有关
    //此处输出都是8

}

用法

//指针的使用
int a = 10;
int b = 20;
long c = 88;

p1 = &a; //p1指针指向a
p2 = &c;
cout << "p1:" << p1 << endl;
cout << "p2:" << p2 << endl;

//如何通过指针获取内容
cout << "*p1:" << *p1 << endl;  //*p1:10
cout << "*p2:" << *p2 << endl;  //*p2:88
*p1 = 33;
cout << "a:" << a << "\t*p1:" << *p1 << endl;  //a:33    *p1:33

无效指针

定义一个指针后,如果不进行初始化,指针的内容就是不确定的。如果这时把它的内容当成一个地址去访问,那访问的是不存在的对象;如果访问到的是系统核心区域,修改其中的内容就有可能导致系统崩溃。这样的指针就是“无效指针”,也被叫做“野指针”。

int *p1;
//*p1 = 100   //直接解引用,危险!指针没有初始化,是无效指针

空指针

如果先定义了一个指针,但不确定它要指向哪一个对象,可以先初始化为“空指针”。空指针不指向任何对象。

//空指针
int *np = nullptr;  //空指针的字面值常量,推荐使用
np = NULL;  //预处理变量
np = 0; //只有0可以初始化,让其指向一个未被使用的内存

int zero = 0;
//np = zero  //该初始化行不通

void *ptr

// void *ptr
int a = 10;
char b = 'c';
long d = 67.2;

int *p1 = &a; //p1只能指向int类型

//想要一个能指向任意类型的指针
void *ptr;
ptr = &a;
ptr = &b;
ptr = &c;

// cout << *ptr << endl; //错误,void类型指针只能用来存储地址,但是不能解引用


指向指针的指针

也叫“二级指针”,用连续两个“*” 表示,如果是三级指针则用三个表示。
C++ 复合数据类型:指针_第3张图片

    // 指向指针的指针
    int i = 22;
    int *p5 = &i;
    int **pp5 = &p5;

    cout << "i:\t" << i << endl;
    cout << "p5:\t" << p5 << endl;
    cout << "pp5:\t" << pp5 << endl;
    cout << "*p5:\t" << *p5 << endl;
    cout << "*pp5:\t" << *pp5 << endl;
    cout << "**pp5:\t" << **pp5 << endl;

/*输出
i:      22
p5:     0x61fdc8
pp5:    0x61fdc0
*p5:    22
*pp5:   0x61fdc8
**pp5:  22
*/

指向常量的指针

//指向常量的指针
const int i = 10, j = 20;
const int *p = &i;
cout << "p\t" << p << endl;
cout << "*p\t" << *p << endl;
//*p = 15 //错误,常量不可修改
p = &j;  //但是指针指向的对象可以换
cout << "*p\t" << *p << endl;

指针常量

int x = 10; 
int y = 20; 
int *const ptr = &x; // 定义一个指向整型变量的指针常量,指向 x

cout << "x 的值为:" << x << endl;
cout << "通过指针访问 x 的值:" << *ptr << endl;

// 尝试修改指针指向的地址
// ptr = &y; // 这行代码会导致编译错误,因为 ptr 是一个指针常量,不能再指向其他地址

// 通过指针修改所指向地址的内容
*ptr = 100;
cout << "修改后,x 的值为:" << x << endl;

指针和数组

用到数组名时,编译器一般都会把它转换为指针,这个指针就指向数组第一个元素。所以也可以用数组名给指针赋值

//指针和数组的关系
int arr[5] = {1, 2, 4, 5, 6};
cout << "&arr\t" << &arr << endl;
cout << "arr\t" << arr << endl;
cout << "&arr[0]\t" << &arr[0] << endl;
cout << "arr+1\t" << arr + 1 << endl; // arr+1 相当于是arr[1]的地址
cout << "&arr[1]\t" << &arr[1] << endl;

int *ptr = arr;
cout << "ptr\t" << ptr << endl;
cout << "*ptr\t" << *ptr << endl;
cout << "ptr+1\t" << ptr + 1 << endl;
cout << "*(ptr + 1)\t" << *(ptr + 1) << endl;
   
输出:
&arr    0x61fe00
arr     0x61fe00
&arr[0] 0x61fe00
arr+1   0x61fe04
&arr[1] 0x61fe04
ptr     0x61fe00
*ptr    1
ptr+1   0x61fe04
*(ptr + 1)      2

指针数组和数组指针

int arr[5] = {1, 2, 3, 4, 6};
//指针数组,本质是数组,数组的所有的元素都是同类型的指针
int *pa[5]; 
cout << "sizeof(pa)\t" << sizeof(pa) << endl;
pa[0] = arr;
pa[1] = arr +1;
cout << "pa[0]\t" << pa[0] << endl;
cout << "*pa[0]\t" << *pa[0] << endl;

输出
sizeof(pa)      40
pa[0]   0x61fe00
*pa[0]  1

//数组指针,本质是指针,指向一个数组 
int (*ap)[5] = &arr;
cout << "sizeof(ap)\t" << sizeof(ap) << endl;
cout << "ap\t" << ap << endl;
cout << "*ap\t" << *ap << endl;
cout << "**ap\t" << **ap << endl;
cout << "*(*ap + 1)\t" << *(*ap + 1) << endl;

输出:
sizeof(ap)      8
ap      0x61fe00
*ap     0x61fe00
**ap    1
*(*ap + 1)      2

你可能感兴趣的:(C++学习记录,c++,开发语言)