在写c语言程序前先干啥,奇怪的C语言代码,在变量前加上(void)是什么操作?有什么用?...

C语言的语法极其简洁,即使是初次接触编程语言的初学者也能很快学完它的语法。不过,C语言也是一门“灵活得过了头”的编程语言,对于很多初学者来说,编写C语言程序就好像拿着一堆最基本的砖块,要修建一座大厦一样,茫然找不到方向。

06a9df81e1c049dff4f30fed9077df78.png茫然找不到方向

奇怪的C语言代码

对于初学者来说,阅读项目源代码是学习和巩固C语言编程能力的一个好方法——从前辈们的一些优秀C语言项目中,我们能够学到很多编写程序方面的思考方式,也就是一些程序员所谓的“编程思维”,看得多了,编写C语言程序自然就手到擒来了。

不过虽然C语言的语法简单,但是我们总会看到一些令人迷惑的代码,例如下面这个函数,它来自某个开源项目,为了讨论主题,我将一些不相关的细节略去了:

void *fun(void *ud, void *ptr, int size){

(void) ud;

(void) size;

// 其他代码,未用到 ud 和 size 参数

...

}

fun() 函数中省略掉的代码没有使用到 ud 和 size 参数,这里有两个问题:一是既然用不到这两个参数,为什么不删去它们呢?再就是两个参数前的 (void) 类型转换有什么用呢?

1f074e7212e1ae0f490d8ee242454292.png为什么不删除多余参数呢?

首先考虑第一个问题

前文提到 fun() 函数来自一个C语言程序开源项目,该项目比较复杂,但是我们知道再复杂的程序项目也是一行一行代码敲出来的,而且,在后续的开发中,可能会修改之前的设计。明白这一点,要回答第一个问题就简单了。

可能在之前的设计中,fun() 函数是用到了 ud 和 size 参数的,只是后来的设计发现 fun() 函数不必使用这两个参数,但是发现整个C语言项目由大量使用 fun() 函数的代码。

如果删去这两个参数,那么 fun() 函数的原型就改变了,开发人员将不得不逐个修改整个C语言项目中所有调用 fun() 函数的代码,这样的工作量巨大,极其容易给C语言项目引入 bug。因此,倒不如继续保留 fun() 函数的原型不变了。

另外,读者应该已经知道C语言是不支持重载的,因为如果该C语言项目需要使用 fun() 函数对接某些 API,那么fun() 函数就必须符合 API 指定的原型,因此 fun() 函数中有未使用的参数其实是“身不由己”的。

b9be411e1f3edfe432502c7956d23e04.png“身不由己”

还有一种情况,fun() 函数可能是某个“函数家族”里的一个,该“函数家族”由一个统一的函数指针管理(为了方便,以及提高效率,实例可参考我之前文章。),因为“统一的函数指针”类型是固定的,所以 fun() 函数的原型必须符合该函数指针的原型,所以,即使 fun() 函数用不到 ud 和 size 参数,也是不能将其删除的,否则就无法通过“统一的函数指针”调用 fun() 函数了。

当然了,也有可能纯粹是因为开发人员懒得修改 fun() 函数原型。现在明白了第一个问题,再来考虑第二个问题。

为什么要在未使用的参数前添加 (void) 呢?

在解答这个问题之前,我们先做一个实验:编写下面这段C语言代码,也即删去 (void)ud 和 (void)size:

void *fun(void *ud, void *ptr, int size){

// 其他代码,未用到 ud 和 size 参数

...

在编译这段C语言代码时,编译器常常会给出下面这样的“参数未使用(unused parameter)”警告信息:

t.c: In function ‘fun’:t.c:3:22: warning: unused parameter ‘ud’ [-Wunused-parameter]

799389a467af99edf166e2e987e61521.png忽略编译器发出的警告信息,是非常不好

很多C语言程序员会忽略编译器发出的警告信息,但这是非常不好的习惯,解决警告信息能够帮助我们最大程度地避免最终C语言程序出现bug。要解决“参数未使用(unused parameter)”警告信息,最直接的方法就是使用它了:

void *fun(void *ud, void *ptr, int size){

ud;

// 其他代码,未用到 ud 和 size 参数

...

}

但是编译器又会给出“C语言语句无效”的警告信息:

t.c:5:5: warning: statement with no effect [-Wunused-value]

ud; ^~

为了避免出现这样的警告信息,我们当然可以对 size 和 ud 参数做一些其他操作,例如:

void *fun(void *ud, void *ptr, int size){

ud = (void *)size;

// 其他代码,未用到 ud 和 size 参数

...

}

可是这样虽然能够避免C语言编译器发出警告,但是这样会让其他阅读代码的程序员费解:“NND,ud = (void *)size;这句到底什么意思呢?”

因此,避免编译器发出参数未使用的警告信息,最好不要像上面这样操作,采用 (void) 操作更好:

void *fun(void *ud, void *ptr, int size){

(void) ud; (void) size;

// 其他代码,未用到 ud 和 size 参数

...

}

C语言程序员都知道 void 表示空,因此(void)ud 和(void)size 显然表示不关心 ud 和 size 的操作。这样一来,我们的意图一眼就能看出,而且还能避免编译器发出警告信息。

小结

在C语言程序开发中,定义函数时,有时会不可避免的定义一些使用不到的参数,这时编译程序时,编译器往往会发出警告信息。C语言程序员不应该忽视每一个警告信息,因此可以借助 (void)操作屏蔽掉这样的警告信息,以免更重要的编译器警告被淹没在信息流里。

be96eea8ea28b69ee8f30eda1ec5d9b2.png点个赞再走吧

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

未经许可,禁止转载。

举报/反馈

### 回答1: 外部变量是定义在文件外部(非函数内部)的变量。它们可以被多个文件中的函数访问和修改。 在 C 语言中定义外部变量的方式是在文件的顶部(非函数内部)添加变量的声明,并在其他文件中通过 extern 关键字来引用它。例如,在文件1中定义外部变量x: ``` int x; ``` 在文件2中引用这个变量x: ``` extern int x; ``` ### 回答2: C语言中,外部变量是指在一个函数之外定义的变量,它的作用域从定义处开始,到文件的结尾为止。外部变量可以在整个C程序中被访问和使用,具有全局的范围和生命周期。 外部变量的意义在于: 1. 数据共享:外部变量可以在不同的函数之间共享数据,避免了函数之间传递参数的复杂性和开销。 2. 面向对象的模块化编程:外部变量可以作为不同模块之间交流和协作的桥梁,方便模块之间的数据传递和共享。 3. 简化代码结构:外部变量可以减少函数内部的参数传递,简化函数的接口和实现,提高代码的可读性。 在C程序中定义外部变量时,需要变量的声明放置在函数之外、程序的顶部。例如: ```c #include <stdio.h> int globalVariable; // 定义了一个外部变量globalVariable int main() { globalVariable = 10; // 可以在函数中直接使用外部变量 printf("%d", globalVariable); return 0; } ``` 在其他函数中使用外部变量时,不需要再次进行声明,只需要直接使用即可。如果在其他函数中需要修改外部变量的值,同样不需要进行声明,直接赋值即可。 需要注意的是,为了安全起见,尽量避免过多使用外部变量,因为它们可能会导致代码的可读性和维护性降低。合理使用外部变量能够提高代码的灵活性和可扩展性,但也需要谨慎使用,遵循良好的编程习惯。 ### 回答3: C语言中的外部变量具有全局作用域,可以被程序中的多个函数共享和访问,有以下几个意义: 1. 数据共享:外部变量可以在程序的多个函数中被访问和修改,实现数据在不同函数之间的共享。 2. 提高代码复用性:通过使用外部变量,可以将需要在多个函数中使用的数据定义为外部变量,避免了重复定义和传递数据的麻烦。 3. 灵活性:外部变量可以在任意的函数中定义和修改,可以方便地在函数之外对其进行操作。 在C程序中定义外部变量有以下几种方法: 1. 在函数之外定义:在所有函数之外定义一个变量,它就成为了外部变量,可以被所有函数访问。例如: ``` int count; // 外部变量定义 ``` 2. 使用关键字extern:在函数之外声明一个外部变量,然后在其他函数中使用关键字extern来引用该变量。例如: ``` extern int count; // 外部变量声明 void func() { count = 10; // 使用外部变量 } ``` 3. 使用头文件:将外部变量的定义放在一个头文件中,然后在需要使用变量的函数中包含这个头文件即可。通过这种方式,可以在多个源文件中共享外部变量需要注意的是,为了避免重复定义,外部变量的定义只能在一个源文件中进行,而其他源文件中只能使用extern关键字来声明该变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值