2024最新C教程:零基础如何快速掌握函数与指针用法(附练习案例)

admin 综合编程开发技术 3


是不是刚学 C 语言就被 “函数” 和 “指针” 拦住了?定义函数时参数总写错,调用的时候要么传错值,要么忘写括号;一到指针更是头大,“*” 和 “&” 像绕口令,好不容易写两行代码,编译就报 “segmentation fault”,根本不知道错在哪。其实啊,函数和指针是 2024 年学 C 语言绕不开的核心,哪怕是零基础,找对方法也能快速掌握。今天兔子哥就用 2024 最新的思路,从函数入门到指针用法,再到实战案例,一步步带新手吃透这两个难点,保证看完就知道该怎么练!

一、先搞懂函数:重复代码太多?用函数打包就对了


现象:写代码时总在复制粘贴,改一处要改十处


小李最近写了个计算圆面积的程序,需要在三个地方用到面积计算,他就把计算公式复制了三遍。后来老师说 “半径单位要改”,他改了两处漏了一处,结果程序出了错。这就是没用到函数的麻烦 —— 重复代码多,维护起来费劲。

1. 函数就是 “代码打包机”,用一次定义多次用


函数其实就是把一段常用代码包起来,起个名字,想用的时候喊名字就行。比如计算圆面积,定义一个circle_area函数,哪里需要就调用哪里:
c运行
#include // 定义函数:计算圆面积,参数是半径rfloat circle_area(float r) {float area = 3.14 * r * r;return area; // 返回计算结果}int main() {// 调用函数,传不同的半径printf("半径2的面积:%f\n", circle_area(2));printf("半径3的面积:%f\n", circle_area(3));return 0;}

这样改公式时,只需要改circle_area里的代码,不用到处找复制的地方,方便多了。

2. 函数参数:别搞混 “形参” 和 “实参”


很多新手在参数上出错,其实简单说:
  • 定义函数时写的参数(比如circle_area(float r)里的r)叫 “形参”,就像个占位符;
  • 调用函数时传的值(比如circle_area(2)里的2)叫 “实参”,是真正要用的数据。
    形参和实参的类型要一样,比如形参是float,实参也得是小数或float变量,不然编译会报错。

3. 虽然函数看起来简单,但传参方式有坑


函数传参分 “值传递” 和 “地址传递”,新手容易搞混:
  • 值传递:实参把值传给形参,形参改了不影响实参。比如传2r,在函数里改r,外面的2不变;
  • 地址传递:传变量的地址(用&),形参改了,实参也会变。这得结合指针用,后面会讲。
    不过话说回来,刚开始不用急着分清,先练熟值传递,后面学指针时再回头看,就容易懂了。

二、再学指针:别被 “地址” 吓到,其实就是 “门牌号”


现象:看到int *p就懵,不知道p*p啥区别


小王对着教程学指针,写了句int *p = 10,编译报错 “类型不匹配”,他盯着屏幕半小时,也没明白为啥不能直接给指针赋值。其实指针存的是地址,不是普通数值,就像门牌号上不能写 “苹果”,得写具体的号码。

1. 指针的本质:存地址的变量


咱们用个生活例子:你家有个盒子(变量a),里面放着糖果(值5),盒子上的门牌号(0x123)就是地址。指针p就是一张纸条,上面写着这个门牌号。
c运行
#include int main() {int a = 5; // 变量a,值5int *p; // 定义int型指针pp = &a; // &a取a的地址,p存这个地址(纸条写上0x123)printf("a的值:%d\n", a); // 盒子里的糖果:5printf("p存的地址:%p\n", p); // 纸条上的门牌号:0x123printf("p指向的值:%d\n", *p); // *p按地址找盒子,拿糖果:5return 0;}

记住:p是地址,*p是地址里的值,&aa的地址,这三个符号别弄混。

2. 指针和函数结合:解决 “值传递改不了实参” 的问题


前面说值传递改不了实参,比如想写个交换两个数的函数,用值传递就不行:
c运行
// 错误示例:值传递,交换不了void swap(int x, int y) {int temp = x;x = y;y = temp;}int main() {int a = 3, b = 5;swap(a, b);printf("交换后:%d, %d", a, b); // 还是3,5,没交换return 0;}

这时候就得用指针传地址,让函数能直接改实参:
c运行
// 正确示例:传地址,能交换void swap(int *x, int *y) {int temp = *x; // 取x指向的值*x = *y; // 把y指向的值给x指向的变量*y = temp;}int main() {int a = 3, b = 5;swap(&a, &b); // 传a和b的地址printf("交换后:%d, %d", a, b); // 输出5,3,成功交换return 0;}

三、练习案例:用函数和指针做个 “成绩处理工具”


光说不练假把式,这个案例能串起所有知识点


功能:输入 3 个学生成绩,用函数求平均分,用指针找最高分。

完整代码(带注释):


c运行
#include // 函数:计算平均分float get_average(int scores[], int n) {int sum = 0;for (int i = 0; i < n; i++) {sum += scores[i];}return sum / (float)n; // 转成float,避免整数除法}// 函数:用指针找最高分void find_max(int scores[], int n, int *max) {*max = scores[0]; // 先假设第一个是最高分for (int i = 1; i < n; i++) {if (scores[i] > *max) {*max = scores[i];}}}int main() {int scores[3], max;// 输入成绩printf("输入3个成绩:");for (int i = 0; i < 3; i++) {scanf("%d", &scores[i]);}// 调用函数求平均分float avg = get_average(scores, 3);// 调用函数找最高分(传max的地址)find_max(scores, 3, &max);printf("平均分:%f,最高分:%d", avg, max);return 0;}

新手练习:


  1. 改改代码,让它能计算平均分并判断是否及格(60 分以上);
  2. 试试用指针遍历数组,替换掉for循环里的下标scores[i]

四、常见错误对照表:这些坑你大概率会踩


错误类型代码示例原因解决
函数调用漏括号printf("hello")写成printf "hello"函数调用必须加()加上()printf("hello")
指针未初始化int *p; *p = 5;指针没指向有效地址,是野指针先让p指向变量,int a; p=&a *p=5;
形实参类型不匹配函数void f(float x),调用f(3)实参是 int,形参是 float3.0或强制转换f((float)3)

五、自问自答:新手最常问的 2 个问题


Q:“函数和指针哪个更难?先学哪个?”
A:建议先学函数,函数是基础,用熟了再学指针。指针确实绕,但结合具体例子(比如交换两个数),慢慢就懂了。学会函数或许能帮助写出更高效的代码,但指针能让代码更灵活,两者都得掌握。
Q:“指针为什么会报‘segmentation fault’?”
A:大多是访问了不该访问的地址,比如指针没初始化就用,或者越界访问数组。关于指针在不同编译器中的细微差异,具体机制待进一步研究,但新手只要保证指针指向有效变量,别越界,基本能避免这个错。
兔子哥觉得,学函数和指针,关键是多动手敲代码,别光看教程。函数要练到 “看到重复代码就想打包”,指针要多画图理解地址和值的关系,比如画个盒子代表变量,旁边标上门牌号(地址),指针就是指向门牌号的箭头。
我刚开始学指针时,写交换函数错了十几次,每次都盯着*&发呆,后来把代码打印出来,在纸上画箭头标地址,突然就明白了。新手别怕错,错一次就记一次原因,慢慢就摸透规律了。现在就打开编译器,从写一个简单的加法函数开始,再试试用指针改它的值,你会发现函数和指针没那么难,动手试试吧!

标签: segmentation 打包机

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~