指针是C/C++的灵魂,理解int与int*的区别是掌握指针的第一步。
内存模型基础
在C/C++中,变量存储涉及两个核心概念:值和地址。理解这两者的关系是掌握int与int*区别的关键。
int的本质
int是一个基本数据类型,直接存储整数值。在内存中,编译器会为int变量分配固定大小的存储空间(通常为4字节):
int num = 42; // 变量num直接存储值42
// 内存布局:[42][0][0][0] (假设小端序)int*的本质
int*是一个指针类型,存储的是内存地址而非实际值。指针变量本身也有地址,它存储的是另一个int变量的地址:
int num = 42;
int* ptr = # // ptr存储num的地址
// 内存布局:ptr -> [地址值] -> [42][0][0][0]核心区别详解
1. 内存占用差异
| 类型 | 典型大小 | 存储内容 | 访问方式 |
|---|---|---|---|
| int | 4 字节 | 整数值 | 直接访问 |
| int* | 8字节(64位) | 内存地址 | 间接访问 |
#include <iostream>
using namespace std;
int main() {
int num = 42;
int* ptr = #
cout << "int大小: " << sizeof(num) << "字节" << endl;
cout << "int*大小: " << sizeof(ptr) << "字节" << endl;
cout << "num值: " << num << endl;
cout << "ptr值(地址): " << ptr << endl;
cout << "ptr指向的值: " << *ptr << endl;
return 0;
}2. 访问方式对比
值语义 vs 引用语义:
int a = 10;
int b = a; // 值拷贝,b是a的副本
b = 20; // 修改b不影响a
int x = 10;
int* px = &x; // px指向x的地址
*px = 20; // 通过指针修改x的值
// 此时x的值变为203. 函数参数传递
这是int与int*最重要的区别之一:
// 值传递 - 函数内修改不影响原变量
void modifyByValue(int n) {
n = 100; // 仅修改副本
}
// 指针传递 - 函数内修改影响原变量
void modifyByPointer(int* pn) {
*pn = 100; // 修改原变量
}
int main() {
int a = 50;
modifyByValue(a); // a仍然是50
int b = 50;
modifyByPointer(&b); // b变为100
return 0;
}使用场景分析
何时使用int
- 基本数值存储:计数器、状态标志、简单计算
- 小对象传递:结构体较小且无需修改时
- 返回值:函数返回简单整数结果
class Counter {
private:
int count; // 基本计数器
public:
void increment() { count++; }
int getCount() const { return count; }
};何时使用int*
- 动态内存管理:需要手动控制对象生命周期
- 数组操作:数组名本质上是指针
- 函数输出参数:需要函数修改调用者的变量
- 数据结构:链表、树等动态结构
// 动态数组管理
int* createArray(int size) {
int* arr = new int[size]; // 动态分配
for(int i = 0; i < size; i++) {
arr[i] = i * 2;
}
return arr; // 返回指针
}
// 链表节点
struct ListNode {
int data;
ListNode* next; // 指针指向下一个节点
};高级应用技巧
指针与数组的关系
int arr[5] = {1, 2, 3, 4, 5};
int* p = arr; // 数组名就是首元素地址
// 以下三种方式等价
cout << arr[2] << endl; // 数组下标
cout << *(arr + 2) << endl; // 指针算术
cout << p[2] << endl; // 指针下标指针的指针
int value = 42;
int* ptr = &value;
int** pptr = &ptr; // 指向指针的指针
cout << **pptr << endl; // 输出42const与指针的组合
const int* p1; // 指向常量的指针,不能通过p1修改值
int* const p2 = &x; // 常量指针,p2不能指向其他地址
const int* const p3; // 指向常量的常量指 针常见陷阱与最佳实践
1. 野指针问题
int* dangerous() {
int local = 42;
return &local; // 危险!返回局部变量地址
} // local在此处销毁,返回悬空指针
// 正确做法
int* safe() {
int* p = new int(42); // 动态分配
return p; // 调用者需要负责delete
}