C语言KR圣经笔记 2.8自增和自减 2.9位运算 2.10赋值
2.8 自增和自减操作符
C提供了两个不同寻常的操作符,用于对变量进行自增和自减。自增操作符++对操作数加上1,而自减操作符 -- 对操作数减去1。我们已经频繁使用++ 对变量进行自增,如:
if (c == '\n')++nl;
不寻常之处在于 ++ 和 -- 既能用作前缀操作符(在变量之前,如++n),又能用作后缀(在变量之后,如n++)。两种情况下,效果都是n递增。不过表达式 ++n 是在它的值被使用之前对n进行递增,而 n++是在它的值被使用之后对n进行递增。这意味着如果不仅要用到递增的效果,还要用到表达式的值时,++n 和 n++ 是不一样的。如果 n 为 5,则
x = n++;
将x设为5,而
x = ++n;
将x设为6。两种情况下,n都会变成6。自增和自减操作符只能用于变量;像 (i+j)++ 这样的表达式是非法的。
当只需要用到递增效果,而不需要值的时候,如
if (c == '\n')nl++;
前缀和后缀是一样的。不过有些情况下会专门要求使用前缀,而有些则专门使用后缀。举个例子,看看下面这个函数 squeeze(s, c) ,将字符串s中出现的所有字符c都删除:
/* squeeze: 从s中删除所有的c */
void squeeze(char s[], int c)
{int i, j;for (i = j = 0; s[i] != '\0'; i++)if (s[i] != c)s[j++] = s[i];s[j] = '\0';
}
每当非c字符出现时,它就被拷贝到当前的 j 位置,而只有这时 j 才会自增,为接收下一个字符做准备。与下面的写法是完全相同的:
if (s[i] != c) {s[j] = c;j++;
}
类似结构的另一个例子来自于我们在第一章写的 getline 函数,其中的
if (c == '\n') {s[i] = c;i++;
}
可以替换成更紧凑的形式:
if (c == '\n')s[i++] = c;
第三个例子可以看看标准库函数 strcat(s, t),它将字符串 t 连接到字符串 s 的末尾。strcat 假定 s 有足够的空间来存放合并的结果。按我们下面的写法, strcat 不返回值,标准库的strcat版本返回指向结果字符串的指针。
/* strcat: 把t拼接到s的末尾;s必须足够大 */
void strcat(char s[], char t[])
{int i, j;i = j = 0;while (s[i] != '\0') /* 找到s的结尾 */++s;while ((s[i++] = t[j++]) != '\0') /* 拷贝t */;
}
由于每个字符都要从 t 拷贝到 s,++后缀同时用于 i 和 j,以保证它们在循环的下一轮时处于正确的位置。
练习2-4,写另一个版本的 squeeze(s1, s2),把字符串s1中出现的所有字符串 s2 都删除
练习2-5,写一个函数 any(s1, s2),返回字符串s2中任意字符在字符串s1中首次出现的位置,如果s1不包含s2的任何字符,则返回-1。(标准库函数 strpbrk 做同样的事,但返回的是位置的指针)
2.9 位运算操作符
C提供了六个位操作符;它们只能用于整型,即 char, short, int 和 long,不管有无符号均可。
& 按位与
| 按位或
^ 按位异或
<< 左移
>> 右移
~ 取反(一元)
按位与操作符 & 经常用于屏蔽位中的某些部分;例如
n = n & 0177
只保留 n 的低7位,其他位都设为0。
按位或操作符 | 用于将一些位打开(设为1)
x = x | SET_ON
会将 SET_ON 中为1的位设置到 x 上对应的位。
按位异或操作符 ^ 的规则是:若两个操作数对应的位不同时,则运算结果中该位设为1,若相同则设为0。
必须把位操作符 & | 和逻辑运算符 && || 区分开,后者隐含的是从左到右的真值计算。
例如,如果 x是1,y 是2,则 x & y 结果为0 ,而 x && y 结果是1。
移位操作符 << 和 >> 分别对它们左边的操作数进行左移或者右移,移动的位数由右边的操作数(必须为正数)指定。这样 x << 2 会将 x 的值左移两位,空出的位补0;这就等于乘以 4。对 unsigned 值进行右移,空位总是补0。对有符号的值进行右移,在有些机器上会填充符号位(算术移位),而有些机器上填充0(逻辑移位)。
一元操作符 ~ 得出整数的反码,也就是说,把每个1都转成0,每个0都转成1。例如
x = x & ~077
把 x 的低6位设为0。注意 x & ~077 不依赖于字长,这种写法比假定字长的写法好,比如 x & 0177700 假定 x 是 16位的值。可移植的写法不涉及额外的开销,因为 ~077 是常量,可以在编译期间求值。
函数 getbits(x, p, n) 可用来演示一些位操作符的用法,该函数返回 x 从位置 p 算起的 n 个位(右对齐)。我们假定第0位是最右边一位,并且 n 和 p 都是合适的正数。例如, getbits(x, 4, 3) 返回第 4,第3 和 第2 位的三个比特,右对齐。
/* getbits:返回从位置 p 开始的 n 个比特 */
unsigned getbits(int x, int p, int n)
{return x >> (p+1-n) & ~(~0 << n);
}
表达式 x >> (p+1-n) 把所需的比特位段移到字的最右边。~0 是所有位均为1;用 ~0 << n 把它左移 n 位,会把最右边的 n 个位变为 0;再对它取反,就得到一个最右边 n 位 都是 1 的掩码。
练习2-6、写个函数 setbits(x,p,n,y),返回值是 x 从位置 p 开始 的 n 个位 被 y 的最右边 n 个位替换后得到的值,x 其他位都不变。
练习2-7、写个函数 invert(x,p,n) ,返回值是 x 从位置 p 开始的 n 个位被翻转(即0变1,1变0)后的结果,其他位都不变。
练习2-8、 写个函数 rightrot(x,n),返回值是整数 x 向右旋转了 n 个位。
2.10 赋值操作符和表达式
i = i + 2
像这种左侧的变量在右边马上重复出现的表达式,可以写成紧凑的形式:
i += 2
其中操作符 += 被称为 赋值操作符。
大部分的二元操作符(像 + 这样左右两边各有一个操作数的操作符)都有一个对应的赋值操作符 op=, 其中 op 是下列操作符之一
+ - * / % << >> & ^ |
设有表达式 expr1 和 expr2,则
expr1 op= expr2
等价于
expr1 = (expr1) op (expr2)
唯一区别是在前面一种形式中, expr1 只会被计算一次。注意 expr2 两边的括号:
x *= y + 1
意思是
x = x * (y+1)
而不是
x = x * y + 1
看看下面这个例子,函数 bitcounts 统计其整数参数中为1的比特位数量。
/* bitcounts: 计算x中为1的比特位数量 */
int bitcounts(unsigned x)
{int b;for (b = 0; x != 0; x >> 1)if (x & 01)b++;return b;
}
将参数 x 声明为 unsigned 可以保证,对 x 做右移时,左边填充的总是0而不是符号位,不管这个程序在什么样的机器上运行。
除了简洁之外,赋值操作符的优势在于它们与人们思考的方式更为一致。我们会说“把 i 加上 2 ”或者“ i 自增 2 ”,而不是“拿到 i 的值,加上 2, 再把结果放回 i ”。因此 表达式 i += 2 比 i = i + 2 更好。另外,对于复杂的表达式如
yyval[yypv[p3+p4] + yypv[p1]] += 2
赋值操作符使代码容易理解,因为读者不必费力地检查两个长表达式是否相等,或者疑惑它们为什么不相等。而且赋值操作符甚至能帮助编译器生成高效的代码。
我们已经知道赋值语句是有值的,可以出现在表达式中;最常见的例子是
while ((c = getchar()) != EOF)...
其他赋值操作符( += -= 等)也能出现在表达式中,不过出现频率会低些。
在所有这样的表达式中,赋值表达式的类型就是它左边操作数的类型,而赋值表达式的值就是赋值之后的值。
练习2-9、在2的补码系统中,x &= (x-1) 删除x最右边的一个比特位。解释为什么。并使用这个发现来写一个更快的 bitcount 版本。




相关文章:
C语言KR圣经笔记 2.8自增和自减 2.9位运算 2.10赋值
2.8 自增和自减操作符 C提供了两个不同寻常的操作符,用于对变量进行自增和自减。自增操作符对操作数加上1,而自减操作符 -- 对操作数减去1。我们已经频繁使用 对变量进行自增,如: if (c \n)nl; 不寻常之处在于 和 -- 既能用作…...
PHP的Excel导出与导入
下载地址(注意php版本大于7.3可能会报错) GitHub - PHPOffice/PHPExcel: ARCHIVED 解压 1、导出 Excel $data[[name>a,age>11],[name>b,age>22],[name>d,age>33], ]; $fileds["name">"名称","age"…...
Ubuntu自建git服务器
Ubuntu 安装 gitlab-ce sudo apt-get update sudo apt-get install gitlab-ce 安装成功 sudo apt-get install gitlab-ce 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 下列【新】软件包将被安装:gitlab-ce 升…...
【面试专题】并发编程篇①
📃个人主页:个人主页 🔥系列专栏:Java面试专题 1.线程和进程的区别 线程和进程都是操作系统中的概念,它们的主要区别如下: 资源分配:进程是操作系统中的资源分配的基本单位,每个进程…...
Linux Centos7安装后,无法查询到IP地址,无ens0,只有lo和ens33的解决方案
文章目录 前言1 查看network-scripts目录2 创建并配置 ifcfg-ens33 文件3 禁用NetworkManager4 重新启动网络服务总结 前言 在VMware中,安装Linux centos7操作系统后,想查询本机的IP地址,执行ifconfig命令 ifconfig结果如下: 结…...
行为型模式-访问者模式
在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就…...
go-kit中如何开启websocket服务
在Go-Kit中,可以使用github.com/go-kit/kit/transport/http包来开启WebSocket服务。以下是一个简单的示例代码,演示了如何在Go-Kit中开启WebSocket服务: package mainimport ("context""fmt""net/http""…...
私有网络的安全保障,WorkPlus Meet内网视频会议助力企业高效会议
在企业内部沟通与协作中,视频会议成为了一种必不可少的沟通方式。然而,传统的互联网视频会议往往受制于网络不稳定因素,给企业带来不便与困扰。WorkPlus Meet作为一款专注内网视频会议的软件,致力于为企业打造高效、稳定的内网视频…...
国际权威媒体聚焦:孙宇晨和波场TRON在迪拜荣获加密行业重磅奖项
近日,在迪拜举行的区块链生态大会(Blockchain Life Conference)上,波场TRON创始人、火币HTX全球顾问委员会委员孙宇晨斩获“年度加密企业家”称号,波场TRON荣膺“年度最佳 Layer 1”大奖。这一消息迅速得到彭博社、雅虎财经、美联社和法国最大媒体之一Le Figaro等国际权威媒体的…...
新闻详情。
<!DOCTYPE html> <html><head><title>新闻</title><meta http-equiv"content-type" content"text/html; charsetutf-8"/><meta name"apple-mobile-web-app-capable" content"yes"/><lin…...
Java面试题-Redis-第二天(Redis持久化、过期键删除策略、内存淘汰策略)
目录 一、Redis持久化机制 二、Redis过期键删除策略 三、Redis内存淘汰策略 一、Redis持久化机制 为了能重用Redis数据,防止系统故障造成数据丢失,我们就需要将Redis中的数据写入到磁盘中,也就是持久化 1. 有哪些方式 有rdb和aof两种方式…...
ElasticSearch快速入门实战
全文检索 什么是全文检索 全文检索是一种通过对文本内容进行全面索引和搜索的技术。它可以快速地在大量文本数据中查找包含特定关键词或短语的文档,并返回相关的搜索结果。全文检索广泛应用于各种信息管理系统和应用中,如搜索引擎、文档管理系统、电子…...
揭秘MySQL数据同步至Elasticsearch的最佳方案与技巧
本文介绍下当前常见的场景之一:Mysql数据同步Elasticsearch的实现方案,这里以电商为例,其实所有相关搜索内容都可以使用此方案。 对于搜索,应该是所有APP必备的基础功能,不同时期有不同的解决方案,本次重点…...
正点原子嵌入式linux驱动开发——Linux RTC驱动
RTC也就是实时时钟,用于记录当前系统时间,对于Linux系统而言时间是非常重要的,就和使用Windows电脑或手机查看时间一样,在使用Linux设备的时候也需要查看时间。本章就来学习一下如何编写Linux下的RTC驱动程序。 Linux内核RTC驱动…...
基于EasyCVR技术的大数据视频汇聚与智能分析平台设计方案
一、背景需求 大数据中心的数据建设如火如荼,针对其中城市中的视频监管及算法分析,各卡口监控、治安监控,电警监控不同网络、不同地域,如何进行视频融合、进行统一监管,则是大数据中心解决方案数据汇聚的重中之重。 现…...
骨传导耳机到底好用吗,到底骨传导耳机是不是噱头呢?
随着社会的飞速发展以及科技的不断提升,人们对健康的关注度也逐渐提高起来。而在这种背景下,骨传导耳机以其独特不可替代的优势,吸引了一大群骨传导爱好者的目光。 那么骨传导耳机是不是噱头呢?其实这种耳机不仅不会堵塞耳道&…...
bitsandbytes 遇到CUDA Setup failed despite GPU being available.
使用conda 管理环境时加载大模型会遇到bitsandbytes无法识别cuda的情况: 此处windows系统: pip install bitsandbytes-windowslinux 系统: 将bitsandbytes版本降低至0.39.0 pip install bitsandbytes0.39.0...
【机器学习】决策树与分类案例分析
决策树与分类案例分析 文章目录 决策树与分类案例分析1. 认识决策树2. 分类3. 决策树的划分依据4. 决策树API5. 案例:鸢尾花分类6. 决策树可视化7. 总结 1. 认识决策树 决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最…...
基于物联网、大数据、云计算、人工智能等技术的智慧工地源码(Java+Spring Cloud +UniApp +MySql)
智慧工地是指利用物联网、大数据、云计算、人工智能等技术手段,为建筑施工现场提供智能硬件及物联网平台的解决方案,实现建筑工地的实时化、可视化、多元化、智慧化、便捷化。智慧工地的建设目标是实现全天候的管理监控,提高施工效率和质量&a…...
Py之pypdf:pypdf的简介、安装、使用方法之详细攻略
Py之pypdf:pypdf的简介、安装、使用方法之详细攻略 目录 pypdf的简介 pypdf的安装 pypdf的使用方法 1、基础用法 pypdf的简介 pypdf是一个免费的、开源的纯python PDF库,能够拆分、合并、裁剪和转换PDF文件的页面。它还可以为PDF文件添加自定义数据…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
