c++ 指针的用法详解

news/2025/1/15 15:08:11/

C++中的指针是一个非常重要的概念,指针变量用于存储其他变量的内存地址。通过指针,程序可以直接访问和操作内存,提高了程序的灵活性和效率。以下是关于C++指针用法的详解。

1. 指针的基本概念

  • 定义指针是一个变量,其值为另一个变量的地址。
  • 类型指针的类型决定了它所指向的变量类型,例如 int*char*double* 等。

2. 指针的声明和初始化

int main() {int var = 10;         // 定义一个整数变量int* ptr = &var;     // 声明指针并初始化为var的地址std::cout << "var: " << var << std::endl;         // 输出 10std::cout << "ptr: " << ptr << std::endl;         // 输出 var 的地址std::cout << "*ptr: " << *ptr << std::endl;       // 输出指针所指向的值,即 10return 0;
}

3. 指针的基本操作

  • 获取地址:使用取地址运算符 & 获取变量的地址。
  • 解引用:使用解引用运算符 * 访问指针所指向的值。
示例:
int main() {int a = 5;int* p = &a;            // p指向a的地址std::cout << "a: " << a << std::endl; // 输出: 5std::cout << "p: " << p << std::endl; // 输出: a的地址std::cout << "*p: " << *p << std::endl; // 输出: 5*p = 20; // 通过指针修改a的值std::cout << "a after change: " << a << std::endl; // 输出: 20return 0;
}

4. 指针的数组

指针可以与数组结合使用,实际上,数组名本身就可以视为指向数组首元素的指针

示例:
int main() {int arr[] = {1, 2, 3, 4, 5};int* ptr = arr; // 指向数组的首元素for (int i = 0; i < 5; ++i) {std::cout << "arr[" << i << "] = " << *(ptr + i) << std::endl; // 使用指针访问数组元素}return 0;
}

5. 指针与动态内存分配

使用指针可以动态分配内存,使用 new 操作符分配内存,使用 delete 操作符释放内存。

示例:
int main() {int* p = new int;  // 动态分配一个整数*p = 30;           // 赋值std::cout << "*p: " << *p << std::endl; // 输出: 30delete p;         // 释放内存// 动态分配数组int* arr = new int[5]; // 动态分配一个整数数组for(int i = 0; i < 5; ++i) {arr[i] = i * 10; // 赋值}for(int i = 0; i < 5; ++i) {std::cout << arr[i] << " "; // 输出: 0 10 20 30 40}std::cout << std::endl;delete[] arr; // 释放数组内存return 0;
}

6. 指针指针

指针变量也可以存储指针的地址,这称为指向指针指针

示例:
int main() {int var = 10;int* ptr = &var;        // 指向var的指针int** ptr2 = &ptr;     // 指向指针ptr的指针std::cout << "var: " << var << std::endl;       // 输出: 10std::cout << "*ptr: " << *ptr << std::endl;     // 输出: 10std::cout << "**ptr2: " << **ptr2 << std::endl; // 输出: 10继续深入了解指针的用法,以下是一些更复杂的指针应用和相关概念。### 7. 常量指针与指向常量的指针- **常量指针**:指针本身可以被修改,但指针指向的内容不能被修改。
- **指向常量的指针**:指针不能修改,但指针指向的内容可以被修改。#### 示例:```cpp
void modifyValue(int* ptr) {*ptr = 20; // 可以修改指针指向的值
}void tryToModifyValue(const int* ptr) {// *ptr = 20; // 错误,不能修改常量指针所指向的值
}int main() {int var = 10;int* p = &var;        // 普通指针const int* cp = &var; // 指向常量的指针modifyValue(p);std::cout << "var after modifyValue: " << var << std::endl; // 输出: 20// tryToModifyValue(cp); // 这行代码会导致编译错误return 0;
}

8. 引用与指针的区别

引用是C++中提供的另一种间接访问变量的方法,以下是指针和引用之间的不同点:

  • 引用必须在声明时初始化,而指针可以在任何时候初始化。
  • 引用不能为nullptr,而指针可以。
  • 引用在使用时更简单,不需要解引用操作符*
示例:
void modify(int& ref) { // 引用参数ref = 30; // 直接修改
}int main() {int var = 10;modify(var); // 传递变量的引用std::cout << "var after modify: " << var << std::endl; // 输出: 30return 0;
}

9. 函数指针

函数指针是一种指向函数的指针,可以用来实现回调函数等。

示例:
#include <iostream>void greet() {std::cout << "Hello, World!" << std::endl;
}void execute(void (*func)()) { // 函数指针参数func(); // 调用传入的函数
}int main() {void (*funcPtr)() = greet; // 声明函数指针并初始化execute(funcPtr);          // 传递函数指针return 0;
}

10. 指针与结构体

指针可以用来访问结构体的成员,C++中使用 -> 运算符来访问指针所指向的结构体的成员。

示例:
#include <iostream>struct Point {int x;int y;
};int main() {Point p1 = {10, 20};Point* ptr = &p1; // 指向结构体的指针std::cout << "Point p1: (" << ptr->x << ", " << ptr->y << ")" << std::endl; // 输出: (10, 20)ptr->x = 30; // 通过指针修改结构体成员std::cout << "Modified Point p1: (" << p1.x << ", " << p1.y << ")" << std::endl; // 输出: (30, 20)return 0;
}

11. 智能指针

C++11引入了智能指针(如 std::unique_ptr 和 std::shared_ptr),它们可以自动管理动态分配的内存,避免内存泄漏。

示例:
#include <iostream>
#include <memory> // 引入智能指针int main() {std::unique_ptr<int> uptr(new int(5)); // 创建一个unique_ptrstd::cout << "Value: " << *uptr << std::endl; // 输出: 5// std::shared_ptr<int> sptr(new int(10)); // 创建一个shared_ptr// std::cout << "Value: " << *sptr << std::endl; // 输出: 10// 在作用域结束时,unique_ptr会自动释放内存return 0;
}

12. 总结

指针在C++编程中非常重要,它们提供了灵活性和强大功能,但也需要小心使用,避免内存泄漏和指针悬挂等问题。通过使用智能指针,可以大大简化内存管理。


http://www.ppmy.cn/news/1522343.html

相关文章

思科网络地址转换5

#网络安全技术实现# #任务五利用动态NAPT实现局域网访问Internet5# #1配置计算机的IP 地址、子网掩码和网关 #2配置路由器A的主机名称及其接口IP地址 Router>enable Router#conf t Router(config)#hostname Router-A Router-A(config)#int f0/0 Router-A(config-if)#i…

Notepad++ 下载安装教程

目录 1.下教程 2.安装教程 1.下教程 Downloads | Notepad (notepad-plus-plus.org) 进入下载地址后选择最新版点击连接 点击链接后&#xff0c;向下滑动&#xff0c;下载适合自己电脑版本的安装包 这里大家没有梯子可能打不开页面&#xff0c;可以直接从本文开头下载。 2.安…

Spring Boot之数据访问集成入门

Spring Boot中的数据访问和集成支持功能是其核心功能之一&#xff0c;通过提供大量的自动配置和依赖管理&#xff0c;极大地简化了数据访问层的开发。Spring Boot支持多种数据库&#xff0c;包括关系型数据库&#xff08;如MySQL、Oracle等&#xff09;和非关系型数据库&#x…

ffmpeg 视频编码及基本知识

理论 H264编码原理&#xff08;简略&#xff09; 1. 视频为什么需要进行编码压缩 降低视频数据大小&#xff0c;方便存储和传输 2. 为什么压缩的原始数据采用YUV格式 彩色图像的格式是 RGB 的&#xff0c;但RGB 三个颜色是有相关性的。 采用YUV格式&#xff0c;利用人对图像的…

redis之zset命令学习

redis之zset命令学习 zset是一个不包含重复元素的字符串集合&#xff0c;且每个元素都会关联一个 double 类型的分数&#xff08;score&#xff09;。这使得有序集合既可以通过成员&#xff08;member&#xff09;来查询&#xff0c;也可以通过分数&#xff08;score&#xff…

ctfshow-php特性(web123-web150plus)

​web123 <?php error_reporting(0); highlight_file(__FILE__); include("flag.php"); $a$_SERVER[argv]; $c$_POST[fun]; if(isset($_POST[CTF_SHOW])&&isset($_POST[CTF_SHOW.COM])&&!isset($_GET[fl0g])){if(!preg_match("/\\\\|\/|\~|…

彻底解决win10系统Tomcat10控制台输出中文乱码

彻底解决Tomcat10控制台输出中文乱码 首先乱码问题的原因通俗的讲就是读的编码格式和写的解码格式不一致&#xff0c;比如最常见的两种中文编码UTF-8和GBK,UTF-8一个汉字占三个字节&#xff0c;GBK一个汉字占两个字节&#xff0c;所以当编码与解码格式不一致时&#xff0c;输出…

封装触底加载组件

&#xff08;1&#xff09;首先创建一个文件名为&#xff1a;InfiniteScroll.vue <template><div ref"scrollContainer" class"infinite-scroll-container"><slot></slot><div v-if"loading" class"loading-sp…