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

相关推荐
散峰而望2 小时前
【数据结构】假如数据排排坐:顺序表的秩序世界
java·c语言·开发语言·数据结构·c++·算法·github
zh_xuan2 小时前
LeeCode 61. 旋转链表
数据结构·c++·算法·leetcode·链表
tobias.b2 小时前
408真题解析-2010-8-数据结构-拓扑排序
数据结构·算法·计算机考研·408真题解析
云深处@3 小时前
二叉搜索树
数据结构·c++
Дерек的学习记录3 小时前
二叉树(下)
c语言·开发语言·数据结构·学习·算法·链表
leaves falling3 小时前
c语言- 有序序列合并
c语言·开发语言·数据结构
代码无bug抓狂人3 小时前
前缀和算法和单调队列算法(经典例题)
数据结构·算法
leaves falling3 小时前
BC68 X形图案
数据结构·算法
June bug3 小时前
【python基础】常见的数据结构的遍历
开发语言·数据结构·python