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的地址和指向的内容都只读,进一步加限制,安全合法。

相关推荐
Pluchon1 分钟前
硅基计划4.0 简单模拟实现AVL树&红黑树
java·数据结构·算法
小龙报16 分钟前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
dllxhcjla20 分钟前
数据结构和算法
数据结构
历程里程碑2 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
sin_hielo2 小时前
leetcode 1653
数据结构·算法·leetcode
李日灐2 小时前
C++进阶必备:红黑树从 0 到 1: 手撕底层,带你搞懂平衡二叉树的平衡逻辑与黑高检验
开发语言·数据结构·c++·后端·面试·红黑树·自平衡二叉搜索树
熬夜有啥好2 小时前
数据结构——排序与查找
数据结构
YuTaoShao2 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法二)排序 + 二分查找
数据结构·算法·leetcode
wangluoqi2 小时前
26.2.6练习总结
数据结构·算法
Yvonne爱编码2 小时前
链表高频 6 题精讲 | 从入门到熟练掌握链表操作
java·数据结构·链表