指针深入学习

一、引言

C++是一种广泛使用的编程语言,它提供了许多高级特性,其中之一就是指针。指针是C++中一个非常重要的概念,它允许程序员直接访问内存,从而可以更高效地处理数据。然而,指针的使用也带来了一定的复杂性,因此本文将对C++指针进行深入的探讨,帮助大家更好地理解和使用指针。

二、指针的基本概念

1. 什么是指针?

指针是一个变量,它的值是一个内存地址。这个地址存储了另一个变量的值。通过指针,我们可以间接地访问和操作这个变量。

2. 指针的类型

指针的类型决定了它所指向的变量的类型。例如,如果一个指针指向一个整数,那么这个指针就是整数指针。C++中有四种基本类型的指针:int*、float*、double*和char*。

3. 指针的声明

在C++中,我们使用星号(*)来声明一个指针。例如,要声明一个整数指针,我们可以这样写:

```cpp
int *p;
```

这里,`p`是一个整数指针,它可以存储一个整数的地址。

4. 指针的初始化

指针在使用前需要初始化,即给它分配一个内存地址。我们可以将一个变量的地址赋给指针,也可以将一个空地址(nullptr)赋给指针。例如:

```cpp
int a = 10;
int *p = &a; // p指向a的地址
int *q = nullptr; // q没有指向任何地址
```

5. 解引用指针

解引用指针是指获取指针所指向的变量的值。我们可以通过在指针前加上星号(*)来实现解引用。例如:

```cpp
int a = 10;
int *p = &a; // p指向a的地址
int b = *p; // b等于a的值,即10
```

三、指针与数组

1. 数组名作为指针

在C++中,数组名本身就是一个指向数组第一个元素的指针。例如:

```cpp
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // p指向a的第一个元素,即1
```

2. 通过指针访问数组元素

我们可以使用指针来访问数组的元素。例如:

```cpp
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // p指向a的第一个元素,即1
int b = *(p + 2); // b等于a[2]的值,即3
```

3. 通过指针修改数组元素

我们可以使用指针来修改数组的元素。例如:

```cpp
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // p指向a的第一个元素,即1
*(p + 2) = 6; // a[2]的值变为6,即a现在为{1, 2, 6, 4, 5}
```

四、动态内存分配与释放

1. new和delete操作符

在C++中,我们可以使用new和delete操作符来动态分配和释放内存。例如:

```cpp
int *p = new int; // 分配一个整数的内存空间,并将地址赋给p
*p = 10; // p指向的整数的值变为10
delete p; // 释放p指向的内存空间
```

2. new[]和delete[]操作符

对于数组,我们可以使用new[]和delete[]操作符来动态分配和释放内存。例如:

```cpp
int *p = new int[5]; // 分配一个包含5个整数的内存空间,并将地址赋给p
for (int i = 0; i < 5; i++) {
    *(p + i) = i + 1; // p指向的数组的值变为{1, 2, 3, 4, 5}
}
delete[] p; // 释放p指向的内存空间(包含5个整数)
```

五、指针与函数参数传递

1. 传值调用与传址调用的区别

在C++中,函数参数传递有两种方式:传值调用和传址调用。传值调用是将实参的值复制一份传递给形参,而传址调用是将实参的地址传递给形参。传值调用不会改变实参的值,而传址调用会改变实参的值。例如:

```cpp
void swap(int a, int b) { // 传值调用,不会改变实参的值
    int temp = a; // temp等于a的值,即10;b的值不变,仍为20;swap函数结束后,temp被销毁,a和b的值仍为10和20;a和b的值没有交换!(错误示例)}*/

/*
*/

void swap(int *a, int *b) { // 传址调用,会改变实参的值
    // a指向的值变为b指向的值;b指向的值变为a指向的值;swap函数结束后,a和b指向的值仍然交换了!(正确示例)
}


    // swap(a, b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(&a, &b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(a, &b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(&a, b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(&a, &b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*a, *b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, *&b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, *b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, &b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, *&b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, *&b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    // swap(*&a, *&b); // 如果改为这种形式,仍然是传值调用,不会改变实参的值!
    swap(&a, &b); // 这是正确的传址调用方式!swap函数结束后,a和b指向的值仍然交换了!
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值