《C陷阱与缺陷》第二章

C语言中的陷阱与错误:函数声明、运算符优先级与常见问题
本文详细解析了《C陷阱与缺陷》第二章的内容,涵盖函数声明的理解,如(float g(),(h)())的含义;介绍了运算符的优先级规则,提供记忆方法并结合实例说明;强调了语句结束分号的重要性,避免遗漏或误增导致的问题;讨论了switch语句中break的使用,以及函数调用和悬挂else的潜在问题。" 50421465,5017853,冒泡排序法实现及K遍扫描结果,"['排序算法', 'C#', '基础编程']

《C陷阱与缺陷》第二章
2.1 ,理解函数声明
提出问题:如何调用0指针指向的函数
分析((void()())0)();
首先分析
float g(),(h)();
在上例中g是一个函数返回值为float指针
h为一个函数指针,此函数返回值为float
即定义一个返回值指向float
的函数指针为
float (h)();
表示这种类型只需要将变量名去掉,即
float (
)();
则返回值为void的函数指针的类型为 void (
)();
如果一个函数指针为fp则调用函数可写为(fp)()或简写为fp();
则以上那个问题可以先将0转换为指针然后再用函数指针调用函数
即可得答案为:(fp)()=>(((void (
)())0))();
如函数有参数,则只需要添加进参数的类型即可
2.2运算符的优先级
0_1524459342597_1524375315962-tim截图20180422133640-resized.png
记忆方法:其他运算符>单目运算符>双目运算符(算数运算符>移位运算符>关系运算符>逻辑运算符)>三目运算符>赋值运算符
实例:tax_rate=income>40000 && residency<5 ? 3.5:2.0
为:tax_rate=(income>40000 && residency<5) ? 3.5:2.0;
补充逗号优先级是最低的
2.3,注意语句结束的分号
逗号作为语句的结束符,遗漏或新增都会出现很大的难以发现的问题
遗漏:

if(n<3)
return
logrec.data=x[0];
logrec.data=x[1];

以上相当于

if(n<3)
return logrec.data=x[0];
logrec.data=x[1];

新增:

if(x[i]>big);
big=x[i];

相当于

if(x[i]>big){}
big=x[i];

2.4,switch语句
注意在编写时每一个分支break的书写,合理调用
2.5,函数调用
f()调用,f为计算函数f的地址
2.6,悬挂else引发的问题
实例:

if(x == 0)
    if (y == 0) error();
else
{
    z = x + y;
    f(&z);
}

相当于

if(x == 0)
    if (y == 0) error();
    else
    {
        z = x + y;
        f(&z);
    }
### C语言第七章函数练习题 #### 题目一:指针操作数组遍历 给定如下代码片段: ```c #include <stdio.h> int main() { char *a[] = {"work", "at", "alibaba"}; char **pa = a; pa++; printf("%s\n", *pa); return 0; } ``` 此段代码展示了如何通过指针访问字符型字符串数组中的元素[^1]。当执行`pa++`语句之后,指针变量`pa`指向的是原数组第二个位置处存储的地址值,即指向了字符串"at"。 #### 题目二:素数检测算法实现 考虑下面这段用于判断整数是否为质数(也称为素数)的功能模块: ```c #include <stdio.h> // 判断n是否为素数 int sushu(int n) { int j = 0; for (j = 2; j < n; j++) { if (n % j == 0) return 0; } return 1; } int main() { int i = 0; // 打印区间内的所有素数 for (i = 100; i <= 200; i++) { if (sushu(i) == 1) { printf("%d ", i); } } return 0; } ``` 上述例子实现了从100到200之间查找并打印所有的素数值功能[^2]。需要注意的是,在实际应用中可以优化该算法以提高效率,比如减少不必要的循环次数等。 #### 题目三:程序错误修正案例分析 对于以下存在潜在逻辑缺陷的源码部分: ```c #define MAX 300 ... if(a[I]>a[j]&&a[I]%2==0){ ... } else if(b[I]>b[j]){ flag=b[I]; b[I]=b[j]; ... } void readDat(); for(i=0;i<cnt;i++){ ... } fclose(fp); ``` 这里有几个地方需要改进: - `I` 和 `i` 的不一致应该被统一; - 文件路径应采用双反斜杠转义符表示法 `"\\\\"`; - 循环条件表达式应当更加严谨地定义边界范围;等等[^3]。 这些题目涵盖了C语言编程中关于函数使用的不同方面,包括但不限于基本语法结构、参数传递机制以及常见陷阱规避等内容。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值