c++ 指针的初始化

发布时间:2024年01月19日

为指针正确赋值可以避免未定义行为(如野指针)。指针可以指向变量、数组、另一个指针(多级指针)、函数等。

指针的初始化可以在声明时进行,也可以在声明之后进行。

初始化为 nullptr

从 C++11 开始,建议初始化未指向任何具体对象的指针为 nullptr。这是一个特殊的值,代表该指针没有指向任何内存地址。在 C++11 之前,NULL 被用来表示空指针。它通常被定义为 0 或者 ((void*)0)。
不过,使用 nullptr 可以提高代码的表达能力,因为 nullptr 的类型是 nullptr_t,而 NULL 实际上是一个整数。
int* pInt = nullptr;// 初始化为 nullptr
int* ptr = NULL; // 在 C++11 之前的代码中常见

初始化为变量的地址

可以通过取地址运算符 & 获取一个变量的地址,并将其赋给指针。这个指针现在指向了该变量。
int value = 5;
pInt = &value; // 指针pInt指向变量value的地址

初始化为数组的地址

也可以使用 new 关键字为一个数组分配内存。
void func()
{
	int arr[] = {1, 2, 3, 4, 5};
	int* ptrToArray = arr; // 数组名 arr 会被转换为指向数组首元素的指针
	/* 也可以指定数组中的特定元素 */
	int* ptrToElement = &arr[2]; // 指向数组 arr 的第三个元素的地址
}
void func1()
{
	int* arrayPtr = new int[10]; // 动态分配一个含有10个整数的数组
	// 记得删除分配的数组,使用 delete[]
	delete[] arrayPtr;
}
初始化为另一个指针的值
int* ptrToAnother = ptrToInt; // ptrToAnother 现在和 ptrToInt 指向相同的地址

初始化为动态分配的内存

使用 new 关键字动态地分配内存,并把返回的地址赋给指针。
int* ptrToDynamicInt = new int; // 使用 new 运算符分配一块内存,并将其地址赋给 ptrToDynamicInt

int* ptr = new int; // 动态分配一个整数,并初始化指针
*ptr = 5; // 设置动态分配的整数的值为 5
// 记得在不需要时删除动态分配的内存
delete ptr;

常量指针和指针常量的初始化

初始化指向常量的指针(指针可以改变,但所指向的值不能改变)。
const int constantVar = 10;
const int* ptrToConst = &constantVar; // ptrToConst 可以指向别的地址,但不能通过 ptrToConst 改变所指向的值
初始化指针常量(指针一旦指向一个地址就不能改变,但可以通过指针改变所指向地址的值)。
int var = 10;
int* const constPtr = &var; // constPtr 的指向不能改变
*constPtr = 20; // 但 constPtr 指向的值可以改变

初始化为函数的指针

void myFunction() {
    // 函数体
}
void (*functionPtr)() = myFunction; // functionPtr 指向函数 myFunction

// 假设有一个返回类型为 int,并接受两个 int 类型参数的函数
int add(int a, int b) {
    return a + b;
}
// 声明指向该类型函数的指针
int (*functionPtr)(int, int);
// 初始化指针,使其指向 add 函数
functionPtr = add;
// 现在,你可以通过指针调用函数
int result = functionPtr(3, 4); // 等价于调用 add(3, 4)

//也可以在定义函数指针时直接初始化
int (*functionPtr)(int, int) = add;

列表初始化(C++11 及以后)

C++11 引入了列表初始化,可以用来初始化指针。
void func()
{
	int* ptrToZero = new int{};        // 分配的内存被初始化为 0
	int* ptrToArrayInit = new int[5]{}; // 分配的数组的每个元素被初始化为 0
}

void func1()
{
	int* ptr = new int{5}; // 使用列表初始化动态分配的整数
	// 或者
	int value = 5;
	int* ptr = &value; // ptr 指向 value
	// 或者
	int* ptr{}; // 初始化为 nullptr
}

用 auto 初始化指针

使用 auto 时的注意事项,必须明确初始化语句
  1. 如果用变量的地址初始化指针,auto 将推导为相应的指针类型。
  2. 如果用 new 操作符初始化指针,auto 也会推导为指向新分配类型的指针。
  3. 当使用 auto 初始化数组名时,它会被推导为指向数组首元素的指针类型。然而,使用 auto& 可以使得推导出的类型为数组类型的引用。
  4. 如果用函数的名字初始化,auto 将推导为指向函数类型的指针。
//指向变量的指针
auto ptr = &var; // 自动检测到 var 是 int 类型,因此 ptr 是 int* 类型的指针

//指向动态分配的内存
auto ptr = new int(5); // ptr 被推导为 int* 类型

//指向数组的指针
int array[] = {1, 2, 3};
auto ptr = array; // ptr 被推导为 int* 类型,指向数组的第一个元素

//指向函数的指针
void myFunction() {
    // 函数体
}
auto funcPtr = myFunction; // funcPtr 被推导为 void(*)() 类型


//使用 auto 初始化 const 指针
/*当使用 auto 来初始化指向 const 数据的指针时,需要在指针声明中明确指定 const。*/
const int constantValue = 100;
auto constPtr = &constantValue; // constPtr 会被推导为 const int* 类型
/* 希望指针本身不可修改时,可以声明指向 const 类型的指针,但如果需要指针本身是 const(即不能指向其他地方),您需要使用后缀声明方式 */
int value = 10;
auto constPtr = &value; // constPtr 会被推导为 int* const 类型,如果 value 声明为 const 的话

/* constPtr 本身是 const 的,它不能再指向另外的地址,但 *constPtr 的值可以改变,除非它指向的是一个 const 对象 */
注意事项
在使用指针时,始终要确保已经给它们赋了一个确定的、有效的地址。随机的、未知的或已释放的内存地址都可能导致未定义的行为。特别地,从未初始化、已释放或已解引用的指针里读取数据,或者向这样的指针里写入数据,都可能导致程序崩溃或其他意想不到的行为。
文章来源:https://blog.csdn.net/weixin_43779276/article/details/135623212
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。