首页 > 其他分享 >C语言:指针1(详细讲解)

C语言:指针1(详细讲解)

时间:2024-07-25 12:29:15浏览次数:9  
标签:const 变量 int C语言 assert 地址 讲解 指针

 目录

指针变量和地址

取地址操作符

指针变量的大小

指针变量类型意义

指针解引⽤

指针的 + - 整数

const修饰指针

const修饰变量

const修饰指针变量

指针的运算

指针+ -整数

 指针的关系运算

野指针

指针未初始化

 指针越界访问

指针指向的空间被释放了

避免野指针

assert断言

传值调⽤和传址调⽤

传值调用

传址调用


下面这一张图,我们可以看到a初始化为20 ,int* p指向a的地址

指针变量和地址

取地址操作符

&取地址操作符可以取出一个变量的地址

下面在32位环境下打印地址,我们可以看到取出a的地址打印

下面这张图,我们在编译过程中,我们也可以查看内存

指针变量的大小

在32位环境下有32根地址总线4X8=32

32位平台下地址是32个bit位,指针变量⼤⼩是4个字节?

在64位环境下有64根地址总线8X8=64

64位平台下地址是64个bit位,指针变量⼤⼩是8个字节

指针变量类型意义

指针解引⽤
int a=20;
int *p = &a;//p指向a的地址
*p = 99;//通过解引⽤把地址变成20,然后进行修改

上面这*p指向的是a的地址,然后再通过解引⽤把地址变成20,然后进行修改成99


下面这代码p如果不解引⽤那么p就是修改int *p指向的地址

int a = 10;
int b = 20;
int *p = &a;//p指向a的地址
p = &b;//这个是修改p指向的地址
//上面修改了p指向的地址,那下面这个修改的就是 b 的数值了
*p = 0;


下面我们可以看到地址是倒着存放的,int是4个字节,11,22,33,44刚刚好4个

每次编译或执行编译器都会重新分配内存空间

当我们执行*p = 0的时候,我们可以发现全部变成0了,因为int *是4个字节。

下面是char *我们可以发现只改了一个地址,因为char *是一个字节

指针的 + - 整数

下面这代码,我们可以看到int *p是int类型的也就是4个字节

p+1我们可以看到往后跳了4个

char * cp是char类型的也就是1个字节

cp+1我们可以看到往后跳了1个

往后跳多少取决于类型是多少,如果类型是8个字节那么就往后跳8个

const修饰指针

const修饰变量

我们可以发现被const修饰变量不能被修改,拥有了常属性

a拥有了常属性,但是不能当常量使用,会报错


我们可以发现被const修饰的变量,用指针的方式通过地址解引⽤后进行修改

举个例子一个房间里大门被const修饰进不去了,可以通过指针也就是翻窗户进去

我们可以发现const也把指针修饰了,也就是说把窗户也关起来了,谁都进不去了

const修饰指针变量

const修饰指针,const在 * 号前面那么数值就不能修改了

const在*号后面的话,地址不能被修改了

指针的运算

指针+ -整数

下面,我们可以发现int *p指向数组首元素地址,for循环通过数组首元素地址加1一直访问到最后一个元素

指针-指针

我们可以看到char* x指向p的首元素地址

然后while循环,每次循环加1,加1跳过类型大小,访问到下一个地址

加到‘\0’停止,每个字符串后面都会有'\0','\0'也是字符串的结束标志

p加到\0停止到了最后一个元素,然后通过最后一个元素的地址减去首元素地址,就可以拿到总共有多少个元素了

 指针的关系运算

野指针

野指针就像一只疯狗,不把狗栓在树上很危险

指针未初始化

指针未初始化那么指针默认就是随机值

 指针越界访问

数组只有10个元素,用指针越界访问到第12个元素,就会成野指针了

指针指向的空间被释放了

下面这个可以运行,但是也是个野指针,很危险

这个函数,返回了n的地址后,这个函数的空间就被释放了,p指向了一个被释放的空间,就是野指针了

避免野指针

当指针没有地址初始化,我们只需要给个NULL就可以避免野指针了

assert断言

使用assert函数我们需要下面这个头文件

#include <assert.h >

assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报
错终⽌运⾏。这个宏常常被称为“断⾔”

用assert可以判断p是不是NULL是NULL就报错并且显示在第几行

p不为空就往下执行

assert() 的使⽤对程序员是⾮常友好的,使⽤ assert() 有⼏个好处:它不仅能⾃动标识⽂件和
出问题的⾏号,还有⼀种⽆需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问
题,不需要再做断⾔,就在 #include <assert.h> 语句的前⾯,定义⼀个宏 NDEBUG 。

如果是我们想让assert全部失效我们可以添加下面这个头文件

#define NDEBUG

然后,重新编译程序,编译器就会禁⽤⽂件中所有的 assert() 语句。如果程序⼜出现问题,可以移
除这条 #define NDBUG 指令(或者把它注释掉),再次编译,这样就重新启⽤了 assert() 语
句。


我们可以看到p是NULL,加上这个头文件,assert失效了,如果有多个assert那么全部失效

当然我们在Release环境下执行会自动过滤assert

传值调⽤和传址调⽤

传值调用

传值调用就是传数值到函数里

下面这代码,在函数里交换后就释放了,

传址调用

传值调用就是传地址解引⽤进行交换,通过地址进行的交换,空间释放了,不会影响地址

标签:const,变量,int,C语言,assert,地址,讲解,指针
From: https://blog.csdn.net/2401_86489950/article/details/140686542

相关文章

  • C语言---二维数组
    1.1概念        从逻辑上有行有列的数组,成为二维数组,相对来讲,只有行这种单一线性结构的数组称为一维数组。二维数组本质上是以数组作为数组元素的数组,即“数组的数组”。定义由行和列组成的二维表格形式元素,二维数组其实也就是矩阵基本格式。访问二维数组需要两个值......
  • 油管视频《编程思维》中的题目,使用C语言编写出来,第三集,炉膛机器人
    题目:假设起初只有一个机器人,他的炉膛里有一个数字0,和另一个未知的任意生成的编码,随着推移,原始机器人自我复制,制造出更多一样的炉膛机器人,被原始机器人自我复制制造出的每一个子机器人的熔炉内,都继承了原始机器人未知的编码,并且有一个属于自己,独一无二的编码刻在外壳,第二代炉膛......
  • 基于springboot+vue.js+uniapp的小程序的英语学习交流平台附带文章源码部署视频讲解等
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaits系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 队列及其C语言实现
    2.3队列2.3.1什么是队列队尾入队,队头出队,一个受限制性的线性表。队列(Queue):具有一定操作约束的线性表•插入和删除操作:只能在一端插入,而在另一端删除。•数据插入:入队列(AddQ)•数据删除:出队列(DeleteQ)•先来先服务•先进先出:FIFO 2.3.2队列的抽象数据类型描述 ......
  • C语言面向对象风格编程解惑-全局变量性能分析
    C语言面向对象风格编程解惑-全局变量性能分析如果你是CPP老手,但在软件开发过程中要求采用C语言作为主要语言,首先遇到的是各种设计模式不方便应用了,感到非常困扰,然后就是认命之后走向另外一个极端,常常会有过度使用全局变量和goto语句的问题。CPP既然是CWithClass,自然不会排斥面......
  • 基于微信小程序+协同过滤推荐算法+SpringBoot+数据可视化的校园顺路代送平台设计和实
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......
  • Tower Of Hanoi - 汉诺塔问题(C语言)
    ☆WelcometoHouse'sblog!☆本人主页:神王豪斯(重拾基础期)-CSDN博客所属专栏:重拾C语言——神王降世的第一步!_神王豪斯(重拾基础期)的博客-CSDN博客1.游戏规则-有三根柱子(通常分别命名为A、B、C)和若干大小不同的圆盘。-最初,所有圆盘按照从大到小的顺序堆叠在一根柱子(比如......
  • 【 C语言 】 C语言设计模式
    一、C语言和设计模式(继承、封装、多态)C++有三个最重要的特点,即继承、封装、多态。我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性。(1)继承性[cpp]viewplaincopytypedefstruct_parent{intdata_parent;......
  • C语言程序设计练习(三)
    1.整型数据类型存储空间大小#include<stdio.h>intmain(){printf("Sizeofint:%zubytes\n",sizeof(int));printf("Sizeofshort:%zubytes\n",sizeof(short));printf("Sizeoflong:%zubytes\n",sizeof(l......
  • C语言:数组
    hello,大家好今天我们来讲解c语言中数组的知识。一、数组的概念数组是⼀组相同类型元素的集合;数组中存放的是1个或者多个数据,但是数组元素个数不能为0。数组中存放的多个数据,类型是相同的。数组分为一维数组和多维数组,多维数组一般比较多见的是二维数组。二、一维数组 1......