当前位置: 首页 > 精选 > 正文

c语言const修饰变量与assert断言详解


const修饰变量

作用:const用于修饰变量使其不能再被修改。

修饰一般的变量

形式:放在类型的前面或者类型与变量之间
如:

int const a = 10;
const int b = 20;

那当我们还要改变a,b的值时,会发生什么呢
如:

 int const a = 10;
 const int b = 20;
a = 20;
b = 10;

运行:
在这里插入图片描述
结果就是编译器报错,运行失败。

修饰指针变量
那么const又是如何修饰指针变量的呢。
当const放在指针变量类型的前面时(即 const int *p),修饰的是 * p,
当const放在指针变量类型和( * )之间时(即 int const *p),修饰的是 * p,
当const放在( * )后面时(即 int * const p),修饰的是 p

const  int* p = &a;//修饰的是*p
int const* p = &a; //修饰的是* p
int* const  p = &a//修饰的是  p

说明:p 是用于存放a的地址的,而*p是用于改变a的值的,可以简单的理解为

p==&a
*p==a

通过代码加深理解:
第一种情况:
在这里插入图片描述
这里看出 *p 已经不能被修改了,那么 p 呢,接下来再看看
在这里插入图片描述
地址发生了改变,也就是p能改变
这里说明了:当const放在指针变量类型的前面时(即 const int *p),修饰的是 * p,而不是 p。
第二种情况和第一种是一样的,只是位置不一样

第三种情况
const放在( * )后面
在这里插入图片描述
这里报错了,p不能被修改,那么*p呢,接下来看看:
在这里插入图片描述
由图看出a的值改变了,说明:当const放在( * )后面时(即 int * const p),修饰的是 p

*总结:当const在 (*)前时,修饰的是 p, 当const在( * )后面时,修饰的是 p

assert断言

作用:验证一个条件是否正确,如果正确则跳过,正常执行后面的代码,否则就会报错,报错的同时告诉你在哪个文件,哪行,这是非常方便的函数,使调试的效率提升。
我们还可以用宏定义控制它开和关闭,当不用了就加宏,用时就注释掉宏

#define NDEBUG

头文件:assert的头文件是 < assert.h > .
使用

assert(条件)

例:

#include<assert.h>
int main() {

	int a = 12;
	assert(a < 0);
	printf("%d\n", a);
	return 0;
}

a大于0不符合条件,此时assert就会断言(报错),告诉你错的是哪里。
在这里插入图片描述

当我们用宏来关闭他时

#define NDEBUG
#include<assert.h>
int main() {

	int a = 12;
	assert(a < 0);
	printf("%d\n", a);
	return 0;
}

结果:
在这里插入图片描述
成功执行了

相关文章:

C语言常见面试题:什么是变量?变量有哪些作用?

变量是编程中的一个基本概念,其定义和用法因编程语言和上下文而异。但通常来说,变量是用于存储数据的容器,这些数据可以是数字、文本、布尔值等。总的来说,变量在编程中扮演着重要的角色,它们使得我们能够有效地存储、操作和使用数据。不同的编程语言和上下文可能会对变量的具体定义和使用方式有所不同,但上述作用是通用的。总的来说,变量和常量都是编程中重要的概念,它们各自有其特定的用途和特性。在编程中正确地使用它们可以帮助我们更好地组织和控制程序的行为。变量和常量在编程中都是重要的概念,但它们之间存在明显的区别。

svn和git的本质区别是什么

上边图中,跨越了区的箭头,它中间的区数据都会同步。例如:git checkout ,它是将本地仓库数据更新到暂存区和工作区的。

C程序的内存空间布局(栈、堆、数据区、常量区、代码区)

较详细的介绍了栈、堆、数据区、常量区、代码区

NRF24L01模块传输MPU6050数据,接收端数据一直为0问题记录

问题描述:一、发射端1、正确配置NRF模块,以及测试过能够正常通信,在发射端的发射线程中进行了如下操作2、这里是获取了陀螺仪的x轴数据,将其而分为两个8位的数据存入发送缓冲区中。因为一个陀螺仪x轴数据是16位的,所以对其进行了拆分,这里只获取gyro的x轴数据进行发送,目的是进行测试。3、这个是发送函数,只要把发送缓冲区的地址作为参数传入就可以发送了。二、接收端1、接收端的NRF24L01模块也正确配置后,在接收线程中进行如下操作2、读取NRF传输过来的数据,存到接收BUF中,然后打印

C语言常见面试题:什么是宏,宏的作用是什么?

宏在计算机科学中是一种批量处理程序命令,它是一种抽象的规则或模式,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。在编译时,预处理器会对宏进行展开,即将宏的内容替换到宏所在的位置。以上是宏的一些主要作用,但并不是全部。在实际编程中,根据需要选择是否使用宏以及如何使用宏,以实现更好的代码组织和可读性。,这样就可以计算出a和b的和。这个例子展示了宏的基本用法和作用。在这个例子中,我们定义了一个宏。,用于计算两个数的和。时,预处理器会将其展开为。

C#winform上位机开发学习笔记3-串口助手的信息保存功能添加

上位机开发的系列学习笔记,避免遗忘多记录多补充多优化

C语言中常用的字符串处理函数和内存操作函数

`memmove(void *destination, const void *source, size_t num)`:将`source`指向的内存块的前`num`个字节移动到`destination`所指向的内存块,即使内存块有重叠部分。返回指向`destination`的指针。- `memcpy(void *destination, const void *source, size_t num)`:将`source`指向的内存块的前`num`个字节复制到`destination`所指向的内存块。

一键式Excel分词统计工具:如何轻松打包Python脚本为EXE

最近,表姐遇到了一个挑战:需要从Excel文件中统计出经过分词处理的重复字段,但由于数据隐私问题,这些Excel文件不能外传。这种情况下,直接使用Excel内置功能好像是行不通的,需要借助Python脚本来实现。为了解决这个问题,我写了一个简单的数据分析和自动化办公脚本,以方便使用。想象一下,即使电脑上没有安装Python,也能通过一个简单的EXE文件轻松完成工作,这是多么方便!因此,我决定不仅要写出这个脚本,还要学会如何将其打包成一个独立的EXE文件。这样,无需Python环境的电脑也能直接运行它

深入三目运算符:JavaScript、C++ 和 Python 比较

三目运算符是编程中常用的条件表达式,它允许我们根据条件选择不同的值。我们将通过具体的例子分别介绍 JavaScript、C++ 和 Python 中的三目运算符,以便更好地理解它们的用法和特性。JavaScript 示例// 例子: 根据条件选择不同的值var x = 10;var y = 20;"x 大于 y" : "x 不大于 y";在这个例子中,如果x大于y,则result的值为 “x 大于 y”,否则为 “x 不大于 y”。C++ 示例// 例子: 根据条件选择不同的值。

【msvcr120.dll】修复电脑出现msvcr120.dll找不到的详细方法

当我们在使用某些程序或游戏时,需要调用这个动态链接库文件中的函数或资源,如果这个文件丢失或损坏,就会导致程序无法正常运行,从而出现“msvcr120.dll丢失”的错误提示。了解了msvcr120.dll丢失的原因后,我们再来看一下msvcr120.dll的作用。我们可以下载一个dll修复工具,使用dll修复工具进行修复操作非常简单(亲测可以修复),它可以自动检测电脑缺失或者损坏的dll文件,如果msvcr120.dll缺失,dll修复工具检测到以后,便会自动安装msvcr120.dll文件。

STM32 SPI通信协议3——读取MAX6675温度传感器

无论是发送还是接收都要判断一下标志位,因为串行通信的缓冲区只有一个,即是发送缓冲区,也是接收缓冲区。接收的时候也是如此。==0的时候,MAX6675启动,此时你需要发送一个激励给他,让他启动,启动后MAX6675开始发送数据,这时候就要用到SPI_I2S_ReceiveData开始接收数据。从MAX6675的数据手册能看到D15是虚假的位,D14-D3是我们的温度数据位,D2在正常工作时为0(低电平)。==0的时候SCK启动,数据线开始发送信息,此时可以读取数据,当数据读完后,再拉高电平停止发送。

Docker的介绍及安装&基本操作命令

在讲到Docker之前,我们先了解虚拟机与容器之间的区别VM(VMware)在宿主机器、宿主机器操作系统的基础上创建虚拟层、虚拟化的操作系统、虚拟化的仓库,然后再安装应用;容器,在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。特性容器虚拟机启动秒级分钟级硬盘使用一般为MB一般为GB性能接近原生弱于系统支持量单机支持上千个容器一般几十个。

JAVA中线程的run()和start()有什么区别?

run() 方法:start() 方法:区别总结:结语我的其他博客在Java中,线程的 和 是与多线程编程相关的两个方法,它们有着不同的作用和用法。 方法是 类的一个普通方法,用于定义线程的主体逻辑。当直接调用 方法时,该方法会在当前线程的上下文中执行,而不会创建新的线程。直接调用 方法,不会实现多线程的并发执行,而只是在当前线程中按照顺序执行 方法的内容。 方法: 方法是 类的一个

ClickHouse & StarRocks 使用经验分享

总结一下,如果是需要分析日志流数据,更加推荐 ClickHouse ,因为 ClickHouse 单机强悍,可以支撑亿级别数据量,架构简单,相比于 StarRocks 也更加稳定,相比集群,更推荐单机 ClickHouse。如果是分析业务流数据,更加推荐 StarRocks ,因为 StarRocks 对于更新场景性能更加,而且 JOIN 性能更好,而且更加推荐部署 StarRocks 集群,可以充分发挥 StarRocks 的性能。

HarmonyOS应用开发学习笔记 包名、icon图标,应用名修改 UIAbility组件介绍、UIAbility启动模式、UIAbility组件基本用法

UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的任务。UIAbility声明:UIAbility编辑完成后,还需要在module.json5上声明,才能使用"name": "EntryAbility", // UIAbility组件的名称。

HarmonyOS 应用开发学习笔记 ets组件生命周期

官网文档里有一句话:一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期经木子测,自定义组件用@Entry修饰了不能触发(onPageShow、onPageHide、onBackPress )回调index.ets 组件(入口组件)能触发 onPageShow、onPageHide、onBackPress、aboutToAppear、aboutToDisappear自定义组件ComponentA。

CopyTranslator11安装包下载及安装教程

2.打开解压得到的文件夹,鼠标右击【copytranslator-setup-11.0.0.exe】,选择以管理员身份运行。1.鼠标右击下载的压缩包选择【解压到copytranslator 11.0】文件夹。4.勾选【为使用这台电脑的任何人安装】,点击【下一步】5.选择安装位置,点击【安装】 建议与我的路径保持一致。6.软件安装中,很快完成。

C++:stack、queue、priority_queue增删查改模拟实现、deque底层原理

一、C++stack的介绍和使用;二、C++queue的介绍和使用;3.1 deque的简单介绍(了解)、3.2 deque的缺陷、3.3 为什么选择deque作为stack和queue的底层默认容器四、priority_queue的介绍和实现4.1 priority_queue的介绍4.1 priority_queue的介绍增删查改模拟实现前言4.1.1 push()4.1.2 pop()4.3 top()、size()、empty()4.1 priority_queue(优先级队列)增删查

C语言字符串处理提取时间(ffmpeg返回的时间字符串)

讲解字符串数据提取案例。

python爬虫之selenium模拟浏览器

之前在异步加载(AJAX)网页爬虫的时候提到过,爬取这种ajax技术的网页有两种办法:一种就是通过浏览器审查元素找到包含所需信息网页的真实地址,另一种就是通过selenium模拟浏览器的方法[1]。当时爬的是豆瓣,比较容易分析出所需信息的真实地址,不过一般大点的网站像淘宝这种是不好分析的,所以利用selenium模拟浏览器的行为来爬取数据是一个比较可行的办法。

Linux:查询当前进程或线程的资源使用情况

proc 目录是一个特殊的虚拟文件系统,它提供了对内核运行时信息的访问,包括进程、设备、网络、文件系统等各个方面的信息。它不是一个真正的文件系统,而是基于内核数据结构的一个接口,通过这个接口可以获取系统的运行时状态。:此目录以进程的 ID(PID)命名,并包含与该进程有关的文件和目录,如之前所讲的 /proc/pid/目录。:该文件包含有关 CPU(处理器)的信息,如厂商、型号、频率、缓存等。:该文件包含有关系统内存的信息,如总内存、可用内存、缓存、交换分区等。

java并发编程九 ABA 问题及解决,原子数组和字段更新

它指的是一个共享变量的值在操作期间从A变为B,然后再从B变回A,而CAS操作可能会错误地认为没有其他线程修改过这个值。AtomicStampedReference 可以给原子引用加上版本号,追踪原子引用整个的变化过程,如: A -> B -> A ->C,通过AtomicStampedReference,我们可以知道,引用变量中途被更改了几次。只要有其它线程【动过了】共享变量,那么自己的 cas 就算失败,这时,仅比较值是不够的,需要再加一个版本号 AtomicStampedReference。

java并发编程八 CAS 与 volatile和原子整数与原子引用

它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存。在java并发编程七六中,可以看到的 AtomicInteger 的解决方法,内部并没有用锁来保护共享变量的线程安全。那么它是如何实现的呢?其中的关键是 compareAndSet,它的简称就是 CAS (也有 Compare And Swap 的说法),它必须是原子操作。获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。

算法模板之栈图文详解

本文主要讲解栈的定义、用数组模拟栈的相关操作以及相关题目介绍,更多精彩内容等你来浏览。

java并发编程七 无锁解决加锁问题

有如下需求,保证 account.withdraw 取款方法的线程安全。首先想到的是给 Account 对象加锁。原有实现并不是线程安全的。withdraw 方法。

java并发编程六 共享模型之内存

因为 t 线程要频繁从主内存中读取 run 的值,JIT 编译器会将 run 的值缓存至自己工作内存中的高速缓存中,减少对主存中 run 的访问,提高效率。1 秒之后,main 线程修改了 run 的值,并同步至主存,而 t 是从自己工作内存中的高速缓存中读取这个变量的值,结果永远是旧值。这种情况下是:线程2 执行 ready = true,切换到线程1,进入 if 分支,相加为 0,再切回线程2 执行 num = 2。I_Result 是一个对象,有一个属性 r1 用来保存结果,问,可能的结果有几种?

java并发编程五 ReentrantLock,锁的活跃性

一间大屋子有两个功能:睡觉、学习,互不相干。现在小南要学习,小女要睡觉,但如果只用一间屋子(一个对象锁)的话,那么并发度很低解决方法是准备多个房间(多个对象锁)将锁的粒度细分。

java并发编程四 Monitor 概念,api介绍与线程状态转换

obj.wait() 让进入 object 监视器的线程到 waitSet 等待obj.notify() 在 object 上正在 waitSet 等待的线程中挑一个唤醒obj.notifyAll() 让 object 上正在 waitSet 等待的线程全部唤醒它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法log.debug("执行....");// 让线程在obj上一直等待下去。

java并发编程四 synchronized锁对象分析和变量线程线程安全分析

这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。所谓的“线程八锁”,其实就是考察 synchronized 锁住的是哪个对象。成员变量和静态变量是否线程安全?局部变量是否线程安全?

Mybatis练习

文章目录配置文件实现CRUD环境准备查询所有数据编写接口方法编写SQL语句编写测试方法起别名解决上述问题使用resultMap解决上述问题小结查询详情编写接口方法编写SQL语句编写测试方法参数占位符parameterType使用SQL语句中特殊字段处理多条件查询编写接口方法编写SQL语句编写测试方法动态SQL单个条件(动态SQL)编写接口方法编写SQL语句编写测试方法添加数据编写接口方法编写SQL语句编写测试方法添加-主键返回修改编写接口方法编写SQL语句编写测试方法删除一行数据编写接口方法编写SQL语句编