函数的调用与指针初探
函数的调用与指针初探
一、背景
利用二分法求函数的根
二、代码实现
1 | |
函数的声明
提前告诉编译器 “存在这样一个函数”,并说明函数的返回值类型、名称和参数类型
编译器先看到
f()的声明,知道它是一个接收两个double、返回double的函数函数的定义
完整描述函数的功能逻辑,包括参数的具体处理步骤和返回结果
函数的调用
在需要的地方(如
main函数中)通过函数名和实际参数,触发函数定义中的逻辑执行,完成特定任务(如计算、打印、数据处理等)
三、科学计数法
在 C 语言(以及多数编程语言)中,科学计数法的写法略有简化,用 e 或 E 代替 “×10ⁿ”,格式为:数字e指数 或 数字E指数
举例说明:
- **
1e-2**对应数学中的 1 × 10⁻²,即 (1 \div 10^2 = 1 \div 100 = 0.01)。 - **
2.5e3**对应 2.5 × 10³,即 (2.5 \times 1000 = 2500)。 - **
3e-5**对应 3 × 10⁻⁵,即 (3 \div 100000 = 0.00003)。 - **
6.02E23**(科学常数阿伏伽德罗常数)对应 6.02 × 10²³,是一个极大的数。
核心规则:
- 指数为 正数 时,表示乘以 10 的幂(数值变大);
- 指数为 负数 时,表示除以 10 的幂(数值变小);
- 尾数可以是整数(如
1e3)或小数(如2.5e-2)。
四、备注
1.可以没有函数的声明,直接把函数的定义放到主函数的前面吗?
可以。如果将函数的定义放在主函数(main函数)之前,此时函数定义本身就兼具了 “声明” 的作用,因此可以省略单独的函数声明。
只适合函数代码比较简单的程序,否则如果头重脚轻,程序就显得不好看
2.可以将函数返回值类型改为void吗?
可以,但需要注意:void表示函数没有返回值,因此函数体内不能有return 表达式,如果改为void f(),函数的功能需要调整 —— 比如直接在函数内部打印结果,而不是通过return返回给调用者
例如:
1 | |
3、函数定义的括号里面参数名称可以省略吗?
在函数定义中,参数名称不能省略。
函数定义的核心是实现函数的具体逻辑,而参数名称是函数体内操作输入数据的 “标识”。如果省略参数名称,函数体中将无法引用这些参数,导致逻辑无法实现,编译器会直接报错。
番外
可以将中间的if判断逻辑封装到独立函数中吗
可以,代码实现:
1 | |
我自己写的代码:
1 | |
密码的,竟然报错了!
问了一下豆包:
你的代码中存在一个典型的 “值传递” 导致的逻辑错误,具体问题出在 judge 函数对 x1 和 x2 的修改无法作用到 main 函数中。
问题分析:
C 语言函数参数传递默认是 值传递—— 函数接收的是实参的 “副本”(复制了一份值),而非变量本身。在你的代码中:
main函数中的x1和x2是原始变量。- 调用
judge(x1, x2, x0, fx1, fx0)时,judge函数接收的是x1和x2的 “副本”(函数内部的局部变量x1和x2)。 - 在
judge函数中修改x1 = x0或x2 = x0,只能改变这个 “副本” 的值,无法影响main函数中原始的x1和x2。
因此,循环中 x1 和 x2 ==始终保持初始值不变==,导致二分法无法正常缩小区间,可能陷入死循环或计算错误。
解决方案:
需要通过 指针 传递 x1 和 x2 的地址,让 judge 函数能直接修改 main 函数中的原始变量。
问题解决:
AI在这里解释的很清楚,”仔细翻翻,看看有什么好东西”:
在 C 语言中,指针是一个非常核心的概念,它的本质是存储变量的内存地址。理解指针的作用和实现方式,能帮你搞清楚为什么之前的代码需要用指针才能正确修改main函数中的x1和x2。
一、指针的核心作用:间接访问和修改变量
C 语言函数参数默认是 “值传递”—— 函数内部的参数只是外部变量的副本(复制了一份值)。如果想让函数内部修改外部变量的值,就必须通过指针 “绕个弯”,直接操作变量的内存地址。
举个生活例子:
- 假设
main函数中的x1是一个放在 “房间 A” 里的变量(内存地址是0x1000,值为1.0)。 - 如果不用指针,
judge函数拿到的x1是 “房间 A” 里值的副本(放在 “房间 B”,地址0x2000,值也是1.0)。此时在judge里改x1,只是改了 “房间 B” 的值,“房间 A” 的x1完全不变。 - 如果用指针,
judge函数拿到的是 “房间 A” 的地址(0x1000)。通过这个地址,judge可以直接去 “房间 A” 里修改x1的值,main函数自然能看到变化。
二、指针的实现方式(结合你的代码)
我们通过修改后的judge函数,一步步看指针是如何工作的:
1. 指针变量的定义
1 | |
double *x1表示:x1是一个指针变量,它专门用来存储double类型变量的内存地址。*在这里是 “指针声明符”,告诉编译器 “x1不是普通的double变量,而是指向double变量的指针”。
2. 传递变量的地址(调用函数时)
1 | |
&x1中的&是 “取地址符”,作用是获取main函数中x1变量的内存地址(比如0x1000)。- 此时,
judge函数的参数x1(指针变量)会接收到这个地址(0x1000),即x1指向了main中的x1变量。
3. 通过指针修改外部变量(函数内部)
1 | |
*x1中的*是 “解引用符”,作用是 “通过指针x1存储的地址,找到它指向的变量”(即main中的x1)。*x1 = x0等价于 “把x0的值放到指针x1指向的内存地址中”,也就是直接修改了main函数中的x1变量。
三、总结:指针如何解决你的问题
在你最初的代码中,judge函数接收的是x1和x2的副本,修改副本不会影响原始变量,导致二分法无法缩小区间。
通过指针:
judge函数拿到了main中x1和x2的内存地址(通过&x1、&x2传递);- 用
*x1、*x2直接操作这个地址对应的变量,实现了 “在函数内部修改外部变量” 的效果; - 最终
main函数中的x1和x2能正确更新,二分法正常工作。
简单说,指针就像一个 “遥控器”,拿着它(指针变量),你可以远程操作它指向的变量(不管这个变量在哪个函数里)。这也是 C 语言中实现函数间数据共享和修改的核心方式。