1.23 指针

一、指针定义

指针 本质上是一个变量,但它存储的不是普通数据(比如整数、字符),而是另一个变量在内存中的地址

cs 复制代码
char val1 = 'a';
char* p = &val1;//val1是什么类型,*p就是什么类型

二、解引用

解引用是针对指针变量 的操作,通过 * 运算符(解引用运算符),访问指针变量中存储的地址所指向的内存空间里的数据

cs 复制代码
int num = 0;
int *p3 = #
*p3 = 5;

注:禁止对NULL进行解引用操作 指针操作会崩溃

int*p;//p变量随机值 p的值可能是内存中任意位置的地址(是未知数)

对一个未知地址(野指针/悬挂指针)进行解引用,指针崩溃

三、const

cs 复制代码
const int val =0;//定义一个指针 指向val
cs 复制代码
const int *p=&val;//需要对*p行为加上常性限制

*p对元素访问正确

*p=1;错误

cs 复制代码
const int **q=&p;//由于p类型是const int *所以q类型是const int **

通过q不能对其**q的值进行修改

cs 复制代码
const int *p=&val;//const修饰*p,说明*p具有常性 *p=1是错误的,p指向之物的值不允许被修改

int*const p=&val;const修饰p说明p具有常性 p=&a是错误的,p的指向不允许被修改

const int*p const p=&val;const修饰p也修饰*p 说明p和*p都具有常性,既不能修改其指针指向,又不可以改变其所指向之物的值
  • const int *pp 指向 const int → 指向的 int 是只读(内容不能改)。

  • int *const pconst pint * → 指针 p 本身是只读(地址不能改)。

  • const int *const p → 指针 p 本身只读,且指向的 int 也只读。

四、权限大小

  • const的指针(int *p):权限最大(能改地址、能改内容)。
  • 限制内容的指针(const int *p):权限中等(能改地址、不能改内容)。
  • 限制地址的指针(int *const p):权限中等(不能改地址、能改内容)。
  • 双限制指针(const int *const p):权限最小(地址和内容都不能改)

1、将权限大赋值给权限小的类型

cs 复制代码
#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int *p1 = &a; // 权限大:地址、内容都能改

    // 权限小:const限制地址,地址不能改、内容能改
    int *const p2 = p1; // 合法!权限大 → 权限小(加"地址只读"限制)
    
    // 验证p2的权限
    *p2 = 30;    // 合法!内容能改
    // p2 = &b;   // 错误!地址不能改

    printf("a = %d\n", a); // 输出:30
    return 0;
}

2.权限可以缩小不允许放大,权限和级别对等情况下考虑缩小问题

cs 复制代码
#include <stdio.h>

int main() {
    int a = 10;
    int *p1 = &a; // 1级:无限制,权限最大

    // 1→2:给内容加限制(const int *p)
    const int *p2 = p1; // 合法!权限缩小(内容从可改→只读)
    // *p2 = 20; // 被限制,无法修改内容

    // 1→2:给地址加限制(int *const p)
    int *const p3 = p1; // 合法!权限缩小(地址从可改→只读)
    // p3 = &a;  // 被限制,无法修改地址

    return 0;
}
cs 复制代码
#include <stdio.h>

int main() {
    int a = 10;
    const int *p1 = &a; // 2级:内容只读、地址可改
    int *p2;

    // 2→1:试图解除内容的const限制(权限放大)
    // p2 = p1; // 编译器直接报错:discards 'const' qualifier
    // 即使强制转换,也属于危险操作(不推荐)
    p2 = (int *)p1;
    *p2 = 20; // 看似能改,但违反const规则,可能导致未定义行为

    return 0;
}

例题:

第一种情况:

int* p = &val//权限对等(无 const→无 const),直接取 val 地址赋值,可通过*p修改 val,也可修改p的地址。

const int* p = &val;//权限缩小 (无 const→限制内容),p指向的内容(*p)只读,不能改*p,但可改p的地址,安全合法。

int* const p = &val;//权限缩小 (无 const→限制地址),p的地址固定,不能改p,但可通过*p修改 val,安全合法。

const int* const p = &val;//权限缩小 (无 const→双限制),p的地址和指向的内容都只读,既不能改p,也不能改*p,安全合法。

第二种情况

int* p = &val;//权限放大 (const 内容→无 const),试图解除 val 的只读限制,编译器报错(discards 'const' qualifier),强行转换会导致未定义行为。

const int* p = &val;//权限对等(const 内容→const 内容),p指向的内容只读,可改p的地址,符合 const 规则

int* const p = &val;//权限放大 (const 内容→无 const 内容),虽限制了p的地址,但解除了内容的 const 限制,编译器报错,违反只读保护

const int* const p = &val//权限缩小 (const 内容→双限制),p的地址和指向的内容都只读,进一步加限制,安全合法。

相关推荐
绝知此事8 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
LuminousCPP9 小时前
数据结构 - 线性表第四篇:C 语言通讯录优化升级全记录(踩坑 + 思考)
c语言·开发语言·数据结构·经验分享·笔记·学习
AI算法沐枫10 小时前
深度学习python代码处理科研测序数据
数据结构·人工智能·python·深度学习·决策树·机器学习·线性回归
m0_6294947312 小时前
LeetCode 热题 100-----26.环形链表 II
数据结构·算法·leetcode·链表
壹号用户12 小时前
用队列实现栈
数据结构·算法
欧米欧13 小时前
C++进阶数据结构之搜索二叉树
开发语言·数据结构·c++
小江的记录本14 小时前
【Java基础】反射与注解:核心原理、自定义注解、注解解析方式(附《思维导图》+《面试高频考点清单》)
java·数据结构·python·mysql·spring·面试·maven
Trouvaille ~14 小时前
【Redis篇】初识 Redis:特性、应用场景与版本演进
数据结构·数据库·redis·分布式·缓存·中间件·持久化
向日的葵00616 小时前
从IO视角深度对比:BST、红黑树、B树、B+树
数据结构·b树
小羊在睡觉17 小时前
力扣239. 滑动窗口最大值
数据结构·后端·算法·leetcode·go