C语言条件语句中调用函数并赋值时的一个小坑
在C语言中,如果在条件语句中赋值,一定要注意符号优先级的问题,比较符号是比赋值符号先执行的。如果同时还调用函数,并将返回值赋给变量,更容易产生错误。
看下面的代码:
int increase(int a) {
return a + 1;
}
int main(int argc, char* argv[]) {
int count = 0;
while (count = func(count) < 10) {
// ...
}
return 0;
}
我希望循环执行10次。但这段代码会陷入死循环。这是因为语句
while (count = func() < 10)
是先调用func(count),将其返回值与10比较,然后将比较的结果赋值给count。由于count原始值为1,所以func(count)返回值为2,2 < 10是真,从而count新赋值后为1。之后,count的值在每次循环都是1,因此无法退出循环。
正确的写法,要么是加上括号:
while ((count = func(count)) < 10) {
// ...
}
但我个人认为这样写不是很好看,所以我更愿意写成:
do {
count = func(count);
// ...
} while (count < 10);
类似的情形是从TCP套接字中读取数据时:
while (str_len = read(client_sock, buf, BUF_SIZE) != 0) {
buf[str_len] = 0;
printf("Message from client: %s\n", buf);
}
假设客户端发送了字符串hello,并已经全部到达本机的套接字缓冲区。第一次循环时,由于read()返回值大于0,所以str_len值为1,只会在屏幕打印h。
由于str_len为1,所以会开始第二次循环,但实际上之前已经读到所有字符并存到buf数组,只是在错误的地方加上了字符串结束符。此时套接字缓冲区已经为空,所以程序会在read()函数处阻塞。
注意,缓冲区为空并不会使read()返回0,只有读取到客户端发送的EOF(客户端关闭套接字时发送)才会使read()返回0。
正确的写法:
do {
str_len = read(client_sock, buf, BUF_SIZE);
buf[str_len] = 0;
printf("Message from client: %s\n", buf);
} while (str_len != 0)
C语言条件语句中调用函数并赋值时的一个小坑的更多相关文章
- 理解 React Hooks 心智模型:必须按顺序、不能在条件语句中调用的规则
前言 自从 React 推出 hooks 的 API 后,相信大家对新 API 都很喜欢,但是它对你如何使用它会有一些奇怪的限制.比如,React 官网介绍了 Hooks 的这样一个限制: 不要在循环 ...
- MongoDB数据实体中的ObjectId序列化成json的一个小坑
很多时候我们都需要对实体对象进行序列化与反序列化,而ObjectId类型,只能用mongo的驱动以bson格式来序列化,但我们对外的交互,一般是json格式. 有两种解决方案: 1.自己写一个json ...
- 关于sniff函数的一个小坑
最近在用scapy模块写一个关于WiFi的脚本时用到sniff函数,其中遇到了一个小坑,记录如下: sniff函数是在指定网卡上每次嗅探到一个数据包后然后将它传给prn指定的函数.
- javascript中 if条件语句中的判断条件类型总结
在所有编程语言中if是最长用的判断之一,但在js中到底哪些东西可以在if中式作为判断表达式呢? 例如如何几行,只是少了一个括号,真假就完全不同,到底表示什么含义呢 var obj={}; obj.Fu ...
- C语言结构体中的函数指针
这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in ...
- Oracle中,利用sql语句中的函数实现保留两位小数和四舍五入保留两位小数
Oracle中,利用sql语句中的函数实现保留两位小数和四舍五入保留两位小数: select trunc(1.23856789,2) from dual round(m,n) 可以四舍五入 trunc ...
- oracle赋值问题(将同一表中某一字段赋值给另外一个字段的语句)
将同一表中某一字段赋值给另外一个字段的语句update jxc_ckmx ckmx1 set ckmx1.ddsl = (select ckmx2.sl from jxc_ckmx ckmx2 whe ...
- oracle 在C# 中调用oracle的数据库时,出现引用库和当前客户端不兼容的问题解决方案
oracle 在C# 中调用oracle的数据库时,出现引用库和当前客户端不兼容的问题解决方案 解决方案 1.直接引用 Oracle.ManagedDataAccess.Client.dll动态库即 ...
- UPDATE语句中SET部分列赋值的先后顺序有影响么?
昨天研发同事问我个问题,UPDATE语句中SET部分列赋值的先后顺序会影响结果么?以前没考虑过这个问题,因为通常我们都会UPDATE时给列赋予一个确定的值,而不是一个依赖于其他列的值. 测试环境: D ...
- mysql url 连接配置的一个小坑。 工作中不会遇到。 学习的时候会
<property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> & ...
随机推荐
- Solutions:Elastic workplace 搜索:随时随地搜索所有内容 (一)
- 分布式存储系统之Ceph集群部署
前文我们了解了Ceph的基础架构和相关组件的介绍,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16720234.html:今天我们来部署一个ceph集群: 部 ...
- 一篇文章带你掌握主流基础框架——Spring
一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...
- Kafka之安装
Kafka之安装 一.下载kafka 此博客只讲述kafka0.8和kafka1.0两个版本 更改kafka下的/home/bigdata/kafka/config/server.properties ...
- linux操作系统运行一个java程序并外网访问
(一)安装jdk 1.新建文档java : mkdir java 2.进入java并且下载jdk 下载jdk : wget --no-check-certificate --no-cooki ...
- Hyperf 接入阿里云ACM应用配置管理中心
参考: 阿里云文档:https://help.aliyun.com/document_detail/85466.html?spm=a2c4g.11186623.6.550.43cb42d4Af4Tu0 ...
- python基础之open函数和路径处理
前言 本次内容主要介绍文件处理open函数以及路径处理. 一.open函数 根据前面介绍的函数调用方式,调用open函数. #open函数调用 open() TypeError: open() mis ...
- 【React】学习笔记(二)——组件的生命周期、React脚手架使用
原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...
- SoringCloud(四) - 微信获取用户信息
1.项目介绍 2.微信公众平台 和 微信开放文档 2.1 微信公众平台 2.1.1 网址链接 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?ac ...
- 手记系列之二 ----- 关于IDEA的一些使用方法经验
前言 本篇文章主要介绍的关于本人在使用IDEA的一些使用方法,一些常用设置,一些插件推荐和使用.请注意,本文特长,2w多字加上几十张图片,建议收藏观看~ 前提准备 idea官网: https://ww ...