• C++
  • 在C++里,指针是一种极为关键的变量类型,它的作用是存储内存地址

  • @ 2025-7-19 15:18:17

在C++里,指针是一种极为关键的变量类型,它的作用是存储内存地址。接下来,我会通过一系列简单易懂的示例,带你深入了解指针的基本概念、实际用途以及相关注意事项。

一、指针的基本概念

指针本质上也是一种变量,但它存储的不是普通的数据,而是内存地址。通过这个内存地址,就能访问存储在该地址上的数据。

下面是指针的基本声明和初始化方式:

int num = 42;       // 定义一个整型变量num,值为42
int* ptr = #    // 定义一个指向整型的指针ptr,并将其初始化为num的地址

这里需要留意几个关键符号:

  • *:在声明时,它表明这是一个指针变量;在使用时,它的作用是解引用,也就是获取指针所指向的值。
  • &:取地址运算符,用于获取变量的内存地址。

二、指针的基本操作

下面为你展示指针的常见操作示例:

#include <iostream>
using namespace std;

int main() {
    int num = 42;
    
    // 1. 声明指针并初始化
    int* ptr = &num;
    
    // 2. 输出变量的值和地址
    cout << "变量num的值: " << num << endl;       // 输出: 42
    cout << "变量num的地址: " << &num << endl;    // 输出: 0x7ffe...(实际地址)
    
    // 3. 输出指针的值和指针所指向的值
    cout << "指针ptr存储的地址: " << ptr << endl;  // 输出: 0x7ffe...(与num的地址相同)
    cout << "指针ptr指向的值: " << *ptr << endl;   // 输出: 42
    
    // 4. 修改通过指针修改变量的值
    *ptr = 100;
    cout << "修改后变量num的值: " << num << endl;  // 输出: 100
    
    // 5. 空指针
    int* nullPtr = nullptr;  // C++11引入的空指针常量
    cout << "空指针的值: " << nullPtr << endl;     // 输出: 0
    
    return 0;
}

三、指针与数组

在C++中,数组名在很多时候会被隐式转换为指向数组首个元素的指针,下面来举例说明:

#include <iostream>
using namespace std;

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    
    // 1. 数组名作为指针
    int* ptr = arr;  // 等价于 int* ptr = &arr[0];
    
    // 2. 使用指针访问数组元素
    cout << "通过指针访问数组元素:" << endl;
    cout << "*ptr = " << *ptr << endl;       // 输出: 10
    cout << "*(ptr+1) = " << *(ptr+1) << endl; // 输出: 20(指针偏移1个单位)
    
    // 3. 使用指针遍历数组
    cout << "遍历数组:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "arr[" << i << "] = " << *(ptr+i) << endl;
    }
    
    // 4. 指针算术运算
    ptr++;  // 指针向后移动一个单位(移动sizeof(int)字节)
    cout << "ptr++后指向的值: " << *ptr << endl;  // 输出: 20
    
    return 0;
}

四、动态内存分配

在C++中,可以利用newdelete操作符来进行动态内存分配和释放,具体用法如下:

#include <iostream>
using namespace std;

int main() {
    // 1. 动态分配单个变量
    int* ptr1 = new int;      // 分配一个整型大小的内存
    *ptr1 = 100;
    cout << "*ptr1 = " << *ptr1 << endl;  // 输出: 100
    
    // 2. 动态分配数组
    int* arr = new int[5];    // 分配包含5个整型的数组
    for (int i = 0; i < 5; i++) {
        arr[i] = i * 10;
    }
    cout << "动态数组内容:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    
    // 3. 释放内存
    delete ptr1;        // 释放单个变量的内存
    delete[] arr;       // 释放数组的内存
    
    // 4. 野指针问题(释放后未置空)
    ptr1 = nullptr;     // 推荐释放后将指针置空,避免野指针
    
    return 0;
}

五、指针与函数

指针在函数参数传递和返回值方面都有重要应用,下面是具体示例:

#include <iostream>
using namespace std;

// 1. 传递指针作为参数(修改实参的值)
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 2. 返回指针(谨慎使用!)
int* createArray(int size) {
    int* arr = new int[size];
    for (int i = 0; i < size; i++) {
        arr[i] = i;
    }
    return arr;  // 返回动态分配的数组指针
}

int main() {
    // 1. 测试指针参数
    int x = 10, y = 20;
    cout << "交换前: x=" << x << ", y=" << y << endl;
    swap(&x, &y);
    cout << "交换后: x=" << x << ", y=" << y << endl;
    
    // 2. 测试返回指针
    int* arr = createArray(5);
    cout << "动态创建的数组:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    
    // 释放内存,防止内存泄漏
    delete[] arr;
    
    return 0;
}

六、指针的注意事项

在使用指针时,有几个重要的注意事项需要你牢记:

  1. 空指针检查:在解引用指针之前,一定要先确认指针不为nullptr,防止程序崩溃。
  2. 内存泄漏:通过new动态分配的内存,在使用完毕后必须使用delete进行释放,避免内存泄漏。
  3. 野指针:释放内存后,要记得将指针置为nullptr,防止误操作野指针。
  4. 数组越界:使用指针访问数组时,要确保访问范围在数组的有效边界内。
  5. 深拷贝与浅拷贝:当指针作为类成员时,要特别注意拷贝构造函数和赋值运算符的正确实现。

七、常见错误示例

下面为你列举一些使用指针时常见的错误:

// 错误1:未初始化指针(野指针)
int* ptr;
*ptr = 10;  // 危险!ptr指向随机内存地址

// 错误2:释放内存后使用指针
int* ptr = new int;
delete ptr;
*ptr = 20;  // 错误!ptr已成为野指针

// 错误3:重复释放内存
int* ptr = new int;
delete ptr;
delete ptr;  // 错误!重复释放同一块内存

// 错误4:返回局部变量的指针
int* getNumber() {
    int num = 42;
    return &num;  // 错误!num是局部变量,函数返回后内存已释放
}

只要你掌握了上述内容,就能在C++编程中安全且高效地使用指针啦!指针虽然功能强大,但也需要谨慎使用,避免出现各种潜在的问题。

7 条评论

  • @ 2025-7-20 14:30:25
    #include <iostream>
    using namespace std;
    int main()
    {
        // 1. 动态分配单个变量
    	//int* ptr1 = new int;      // 分配一个整型大小的内存 相当于 int* ptr1 = (int*)malloc(sizeof(int));
    	//上面代码相当于创建了一个int类型的变量
    	//C++ new叫做动态内存分配,new是一个运算符 new构造、构建、申请、分配
        //*ptr1 = 100;
    	int* ptr1 = new int(200);// 分配一个整型大小的内存,并初始化为200
    	cout << *ptr1 << endl;// 输出200
    	return 0; // 返回0表示程序正常结束
    }
    
    
    • @ 2025-7-20 14:19:18
      #include <iostream>
      using namespace std;
      int main()
      {
          int arr[5] = { 10, 20, 30, 40, 50 };
          // 1. 数组名作为指针
          int* ptr = arr;  // 等价于 int* ptr = &arr[0];
          //指针也就是地址,一般情况是按照字节编址的 一个字节一个地址
          for (int i = 0; i < 5;i++) {
      		cout << "arr[" << i << "] = " << arr[i] << endl;// 使用数组名访问数组元素 下标访问符
          }
      	cout << endl;// 换行
          for (int i = 0; i < 5; i++) {
              cout << "ptr[" << i << "] = " << *(ptr + i) << endl; // 使用指针访问数组元素
      	}
          cout << endl;// 换行
      	return 0; // 返回0表示程序正常结束
      }
      
      • @ 2025-7-20 14:14:43
        #include <iostream>
        using namespace std;
        int main()
        {
            int arr[5] = { 10, 20, 30, 40, 50 };
            // 1. 数组名作为指针
            int* ptr = arr;  // 等价于 int* ptr = &arr[0];
            //指针也就是地址,一般情况是按照字节编址的 一个字节一个地址
        	//int* int类型的指针,指向int类型的变量,基于int类型的指针+1,加四个字节
        	//一个int类型的变量占用4个字节,所以指针+1会跳过4个字节
        	cout << arr << endl;  // 输出数组的首地址
        	cout << arr + 1 << endl; // 输出数组第二个元素的地址
        	cout << arr + 2 << endl; // 输出数组第三个元素的地址
        	cout << *(arr + 2) << " " <<arr[2]<< endl; // 输出数组第三个元素的地址 []叫做下标运算符,等价于*(arr + 2),即访问数组第三个元素的值
        	return 0; // 返回0表示程序正常结束
        }
        
        
        • @ 2025-7-20 14:01:32

          • @ 2025-7-20 13:53:31

            • @ 2025-7-20 13:51:45
              #include <iostream>
              using namespace std;
              int main()
              {
              	int a = 100;
              	int* p = &a; // 定义一个指针p,指向变量a的地址  &a 是取地址运算符 *是指针运算符
              	cout << "a的值: " << *p << endl; // 输出指针p所指向的变量a的值 *是解引用运算符
              	int& b = a; // 定义一个引用变量b,引用变量a &是引用运算符
              	cout << "a的值: " << b << endl; // 输出变量a的值
              	return 0; // 返回0表示程序正常结束
              }
              
              
              • @ 2025-7-20 13:47:54
                #include <iostream>
                using namespace std;
                int main()
                {
                    int num = 42;       // 定义一个整型变量num,值为42
                    int* ptr = &num;    // 定义一个指向整型的指针ptr,并将其初始化为num的地址
                	//int* 基于int的指针类型
                	cout << ptr << endl;// 输出指针ptr的值,即num的地址
                	cout << &num << endl; // 输出num的地址 &取地址运算符 不是引用符号
                	cout << *ptr << endl; // 输出指针ptr所指向的值,即num的值
                	//*ptr 解引用运算符,获取指针ptr所指向的值 间接访问num的值42
                	cout << num << endl; // 直接输出num的值
                
                	// 通过指针修改num的值
                	*ptr = 100; // 将ptr所指向的值修改为100
                	cout << num << endl; // 再次输出num的值,应该是100
                	return 0; // 返回0表示程序正常结束
                }
                
                • 1