C++指针基础

指针基础

引用

引用变量是对现有变量的引用,它是使用 & 运算符创建的:

string food = "Pizza";  // 声明 food 变量
string &meal = food;    // 引用 food
  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。
#include <iostream>
using namespace std;
int main()
{
   // 声明简单的变量
   int i;
   double d;

   // 声明引用变量
   int &r = i;
   double &s = d;

   i = 5;
   cout << "value of i : " << i << endl;
   cout << "value of i reference : " << r << endl;

   d = 11.7;
   cout << "value of d : " << d << endl;
   cout << "value of d reference : " << s << endl;

   return 0;
}


// value of i : 5
// value of i reference : 5
// value of d : 11.7
// value of d reference : 11.7

为了了解动态内存,首先需要了解指针。我们创建的所有变量都存储在内存中。

指针是一个变量,它将另一个变量的内存地址存储为其值。

定义和访问

int *p;      // 数值类型
p=&a;       // 记录变量a的地址 

必要时要加( ) 来避免优先级的问题
int(*p_arr)[3];    //指向含有3个int元素的数组的指针 
Student* p_struct;     //类或结构体类型的指针
使用 & 运算符访问变量的地址。
使用 * 定义一个指针类型。

int num = 42;

int *p = &num;

cout << p;

使用 星号 * 还用于访问存储在内存地址的值。它称为解除引用运算符
cout << *p;

案例

#include <iostream>

using namespace std;

int main() {
    int num = 42;

    int *p = &num;

    cout << "nums " << num << endl;
    cout << "*p " << p << endl;
    cout << "**p " << *p << endl;

    return 0;
}

// 执行结果
nums 42
*p 0x3bfb3ff894
**p 42

内存空间

在32位操作系统下占用4个字节,64位下占用8个

空指针和野指针

空指针:指针变量指向内存编号为0的空间

用途:初始化指针变量

注意:空指针指向的内存是不可以访问的

野指针:指变量指向非法的内存空间

const修饰指针

const修饰指针----常量指针

特点:指针的指向可以修改,指针指向的值不可以修改

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    int b = 20;
    const int *p = &a;
    *p = 20;  // --错
    p = &b;   // --对
}

const修饰常量----指针常量

特点:指针的指向不可以修改,指针指向的值可以修改

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    int b = 20;
    int *const p = &a;

    *p = 20;  // --对
    p = &b;   // --错
}

指针之间的赋值

指针赋值和int变量赋值一样,就是将地址的值拷贝给另外一个。

指针之间的赋值是一种浅拷贝,是在多个编程单元之间共享内存数据的高效的方法。

int* p1  = &a;
int* p2 = p1;

通过指针改变原数据值

int num = 42;
int *p = &num;

*p = 8;
cout << num;
8

指针和数组

数组的名称实际上是指向其第一个元素的指针。

可以通过递增指针来访问每个元素。

案例1

#include <iostream>
using namespace std;

int main() {

    int arr[] = {2, 4, 6, 8};   // 数组
    int *p = arr;                             // 数组指针-指向了数组的第一个元素

    // 第一个元素
    cout << *p << endl;

    // 第二个元素
    cout << *(p + 1) << endl;

    // 第三个元素
    cout << *(p + 2) << endl;

    return 0;
}

// 执行结果
2
4
6

案例2

#include <iostream>
using namespace std;

int main() {
    int arr2[] = {44, 22, 11, 0};

    int *p2 = arr2;

    for (int i = 0; i < 4; i++) {
        cout << *p2 << endl;
        p2++;
    }

    return 0;
}

44
22
11
0

说明

& 运算符用于访问变量的内存位置。
* 运算符用于访问存储在指针中的内存地址的值。
同样的 * 符号也用于声明指针,它与解除引用运算符不同。

指针和函数

1.值传递

2.地址传递

#include<iostream>
using namespace std;

void swap(int a, int b) {
    int temp = 0;
    temp = a;
    a = b;
    b = temp;
}

void swap2(int *a, int *b) {
    int temp = *a;   // 解指针得到数值
    *a = *b;   
    *b = temp;
}

int main() {
    int a = 10;
    int b = 20;
    //值传递
    swap(a, b);
    cout << a << " " << b << endl;
    //地址传递
    swap2(&a, &b);
    cout << a << " " << b << endl;
    return 0;
}

// 执行结果
10 20
20 10

动态内存

我们需要根据用户输入分配新内存时。 创建动态数组(具有可变大小的数组)

#include <iostream>

using namespace std;

int main() {
    int size = 10;

    int *p = new int[size];    // 通过new来创建一个数组指针

    for (int i = 0; i < size; i++) {
        p[i] = i * i;
    }

    for (int i = 0; i < size; i++) {
        cout << p[i] << ends;
    }
}
0 1 4 9 16 25 36 49 64 81

指针潜在危险

指针的让我们对内存的操作有了很大的自由性,同时也带来了潜在的危险。

产生的原因:

1.定义指针变量的同时未对其进行初始化:
指针在被定义的时候,如果程序不对其进行初始化的话,它会指向随机区域,
因为任何指针变量(除了static修饰的指针变量)在被定义的时候是不会被置空的,它的默认值是随机的。

2.指针所指向的内存空间被释放时,却没有对该指针变量的值(即该指针原来指向的内存空间的地址)进行置空:
我们在用库函数malloc开辟内存空间时,要检查返回值是否为空,如果为空,则开辟失败;如果不为空,则指针指向的是开辟的内存空间的首地址。
指针指向的内存空间在用free()或者delete(注意delete只是一个操作符,而free()是一个函数)
释放后,如果程序员没有对其置空或者其他的赋值操作,就会使其成为一个野指针。

3.指针操作超越变量作用域.

危害规避

1.在定义一个指针时同时初始化为NULL
int *p=NULL;

2.释放指针指向的内存空间时,将指针重置为NULL。
free(p1);        //只释放了p1指向的堆区空间  并没有将指针p1置为空
p1 = NULL;

3..使用时不要超出变量作用
int a[3];
int*p=a;
cout<<p[5];   // 错误使用

参考资料

https://mp.weixin.qq.com/s/cgybk0JWaxPouCJ66vOlGQ

posted @ 2023-10-24 20:33  贝壳里的星海  阅读(4)  评论(0编辑  收藏  举报