C规范编辑笔记(七)

往期文章:

C规范编辑笔记(一)
C规范编辑笔记(二)
C规范编辑笔记(三)
C规范编辑笔记(四)
C规范编辑笔记(五)
C规范编辑笔记(六)

正文:

大家好,今天来分享一下C语言规范编辑笔记的第七篇,分享这个是希望自己后面忘记了可以去复习一下,同时也希望分享给有需要的小伙伴,所以在每一篇的开头,我都加了以往文章的链接~

好了,话不多说,我们直接来看这期的内容:

1、禁止隐式类型转换。建议使用显式转换,特别是在有符号和无符号类型之间。防止有符号数被转换成无符号数的时候会出错。
如以下案例可以看出:

Bad example:
signed int v1 = -1;     //定义v1为有符号整型
unsigned int v2 = 1;    //定义v2为无符号整型
if (v1 < v2)   //这样比较对将v1隐式转换为无符号,而-1转换为无符号后就为无符号int的最大值,所以这样,v1永远不可能大于v2
{
/* v1转换为无符号int,值-1变为UINT_MAX,因此if条件始终为false */
}

Good example:
signed int v1 = -1;
unsigned int v2 = 1;
if (v1 < (signed int)v2)  //通过显示转换,将v2也转换为有符号的
{
/* v2显式转换为有符号整数-条件为true */
}

另外这里需要注意一旦,如果是无符号数用在for循环中,需要注意不能使条件小于0,这样就一直循环下去!!!,如下例子对比:

Bad example:
uint8_t idx;
//以下循环是无限的:idx是无符号的,idx>=0始终为真,因为无符号值不能为负
for(idx = 27; idx >= 0; idx --) {
...
}

Good example:
//有符号整数转换用于避免无限循环
for(idx = 27; (int8_t)idx >= 0; idx --) {
...
}
或者
idx=27;
while (idx >0)
{
...
}

2、建议 - 不要在不同结构的类型上使用指针类型转换。因为这会涉及到自身以外的内存,造成数据错误。如我们通过下述案例可以知道:

Bad example:
#define TAB_SIZE 16U    

typedef struct {
    int32_t magic;
} s_a;      //创建s_a结构体类型

typedef struct {
    int32_t magic;
    int16_t s;
    uint8_t x[TAB_SIZE];
} s_b;      //创建s_b结构体类型

void foo(s_a* structa) {
s_b* p = (s_b*)structa; /* 将其转换为位s_b类型 */
p->magic = 0xBAADCAFE;
p->s = 0xDEAD; /* 结构s_a外部溢出 */
p->x[0] = 4; /* 以及数据被覆盖的风险(缓冲区溢出),因为s_a大小小于s_b,所以必然在内存中被转换为s_b类型的s_a会占用后面其他的内存,造成覆盖掉后面的内存的数据!!! */
}

Good_example:
#define TAB_SIZE 16U

typedef struct {
    int32_t magic;
} s_a;

typedef struct {
    s_a h;       //在s_b结构体里面包含s_a结构体,这样后面只用结构体s_b就可以同时也使用s_a结构里面的参数
    int16_t s;
    uint8_t x[TAB_SIZE];
} s_b;

void foo(s_b* structb) {
structb ->h.magic = 0xCAFEBABE;
structb ->s = 0xBEEF;
structb ->x[0] = 4;
}

从上述两个例子可以对比看出,第一个不好的例子因为将s_a的结构体变量显示转换为s_b结构体类型,造成指针p后面指向的内存空间大小变为了s_b的大小,而超出了s_a本身结构体的范围,所以就会报错,而好的例子中采用包含s_a结构体完美的解决了这个问题。

好了,今天因为两个规范建议用的例子都比较长,所以今天我们就先分享到这里~
我们C规范编辑笔记第八篇见~

在这里插入图片描述
本人水平有限,上述信息仅供学习参考,如有错误和不妥之处,请多多指教。
另外创作不易,请勿抄袭,如果有帮助到大家的话希望大家可以点个赞,谢谢~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OMGMac

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值