c++指针相关

参考:指针声明

常量指针 (Pointer to Constant)

定义:一个指向常量的指针。这意味着指针指向的值不能被修改,但指针本身可以被修改,即可以重新指向其他地址。

声明:const Type* pointerName;

const int* p1;
int x = 10, y = 20;
p1 = &x;   // Valid
*p1 = 50;  // Error
p1 = &y;   // Valid

指针常量 (Constant Pointer)

定义:一个常量指针,它的地址是固定的,不能被修改。但是,通过这个指针,你可以修改它所指向的值。

声明:Type* const pointerName;

int* const p2 = &x;
*p2 = 50;  // Valid
p2 = &y;  // Error

多级指针

先看一段最基础的代码:

int x = 10;
int* p = &x;
int** pp = &p;

解读多级指针应该从右往左看,先看到的是 *pp,代表 pp 是一个指针,然后再看到int*,代表 pp 指向的是一个 int* 型的指针

假设我们在多级指针中添加 const:

  • case1
int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int* *const pp = &p;

我们从右往左分析:先看到的是一个*const,代表pp是一个指针常量,然后看到的是int*,代表pp指向的是一个int*型的指针

有如下测试程序:

int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int* *const pp = &p;
int* *const pp1 = &p1;

**pp = 100;  // Valid

*pp = p1;  // Valid
pp = pp1;  // Error
  • case2
int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int* const* pp = &p;

我们从右往左分析:先看到的是一个 const*,代表 pp 是一个常量指针,然后看到 int*,代表pp指向的是一个int*型的指针

有如下测试程序:

int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int* const* pp = &p;
int* const* pp1 = &p1;

**pp = 30;  // Valid

pp = pp1;  // Valid
*pp = p1;  // Error
  • case3
int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int const* *pp = &p;

我们从右往左分析:先看到的是一个 *pp,代表 pp 是一个指针,然后看到 const*,代表pp指向的是一个常量指针

有如下测试程序:

int x = 10, y = 20;
int* p = &x;
int* p1 = &y;
int const* *pp = &p;
int const* *pp1 = &p1;
pp = pp1;  // Valid
*pp = p1;  // Valid
**pp = 30;  // Error
  • case4
int* ap[2];

解读这种声明时,通常的方法是从变量名开始,然后向外扩展,同时考虑操作符的优先级。在这种情况下,方括号 [](表示数组)的优先级高于星号 *(表示指针)

核心部分:ap 是我们正在声明的变量的名称。
数组大小:[2] 表示 ap 是一个数组,它有两个元素。
元素类型:int* 表示数组的每个元素都是指向整数的指针。

因此,整体来看,int* ap[2] 可以被解读为:ap 是一个数组,包含两个指向整数的指针”。

数组指针

一般格式:
ElementType (*PointerName)[ArraySize];

  • case1
int arr1[3] = {1, 2, 3};
int (*ptr1)[3] = &arr1;
std::cout << "(*ptr1)[1]: " << (*ptr1)[1] << std::endl;  // Should print 2
  • case2
void printArray(int (*arr)[3], int size) {
    for (int i = 0; i < size; ++i) {
        std::cout << (*arr)[i] << " ";
    }
    std::cout << std::endl;
}
printArray(ptr1, 3);  // Should print 1 2 3
  • case3
int arr2[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*ptr2)[2][3] = &arr2;
std::cout << "(*ptr2)[1][2]: " << (*ptr2)[1][2] << std::endl;  // Should print 6

函数指针

基础用法:

#include <iostream>

int f(int x) {
  std::cout << x << '\n';
  return x * x;
}

int main() {
  int (*p)(int) = f;
  int ret = p(10);
  std::cout << ret << '\n';
}

使用 using 简化:

#include <iostream>

int f(int x) {
  std::cout << x << '\n';
  return x * x;
}

int main() {
  using F = int(*)(int);  // 定义了一个指向函数的指针类型
  F p = f;
  p(10);
}

另一种用法:

#include <iostream>

using FuncType = void(int);

void display(int x) {
  std::cout << "Value: " << x << std::endl;
}

void execute(FuncType* func, int value) {
  func(value);
}

int main() {
  execute(display, 42);
}

更多用法:

#include <iostream>

using FuncType = void(int);

void display(int x) {
  std::cout << "Value: " << x << std::endl;
}

FuncType* getFunction() {
  return display;
}

FuncType anotherDisplay;

void anotherDisplay(int y) {
  std::cout << "Another Value: " << y << std::endl;
}

int main() {
  FuncType* funcPtr = getFunction();
  funcPtr(50);
  anotherDisplay(60);
}

函数指针数组的用法:

#include <iostream>

using FuncType = void(int);

void func1(int x) {
  std::cout << "func1: " << x << std::endl;
}

void func2(int x) {
  std::cout << "func2: " << x * 2 << std::endl;
}

void func3(int x) {
  std::cout << "func3: " << x * 3 << std::endl;
}

int main() {
  FuncType* funcArray[3] = { func1, func2, func3 };
  //void (*funcArray[3])(int) = { func1, func2, func3 };

  for (int i = 0; i < 3; ++i) {
    funcArray[i](i + 1);
  }
}
posted @   hacker_dvd  阅读(4)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示