作业总结
两次的作业,都是和指针有关。从第一次的作业开始,我就多次让同学们思考这个问题:为什么要用指针,为什么在函数的形参中要使用指针。如果能够想明白这2个问题,那么同学们应该会指针的了解就差不多足够了,剩下的,就是充分的代码练习。
其实,总的来说,指针这一概念本身很简单,理解起来也并不复杂——指针是一个变量,内部存储的是一个地址,这个地址指向其他的变量/函数(也有可能是空)。
用C语言来表述,就是先声明一个指针,在定义它:
// 以 int 类型为例
int *point; // 声明一个变量,这个变量是一个指针变量
int a;
point = &a; // 定义这个point指向变量a。
int b;
point = &b; // 将 point 指向 b
*point = 5; // 将 b 的值赋值为 5
但是,这里有一个地方特别容易让新手混淆:
int *pointa = &a; // ① 在这种声明的同时定义的,有 * 号
int b;
int *pointb;
pointb = &b; // ② 在定义的时候,假如想要让指针指向一个目标,是不需要 * 号的
*pointa = b; // ③ 当需要对这个指针变量进行解引用,就需要一个 * 号(解引用符号)
虽然仅仅是很简单的几句代码,但是在经验不足的情况下,非常容易混淆,同学们需要在这里多多锻炼。
这里,仅列举几个同学们经常遇到的错误示例:
void findMax(int x,int y,int *pmax){
int *px,*py,max;
*px = x;
*py = y;
if(*px < *py)
max = *py;
else
max = *px;
}
// 调用
int main(){
int x,y,*px,*py,max;
scanf("%d%d",&x,&y);
findMax(*px,*py,&max);
}
在以上的代码中,同学们出现了以下的错误:
- 学了指针,就一下子忘记函数形参是普通变量的直接传普通变量就可以;
- 指针没有定义就直接使用;
findMax
函数中对指针的运用也不熟练,需要先做一个转换再去使用。
int main(){
float op1,op2,*psum,*pdiff;
scanf("%f%f",&op1,&op2);
sum_diff(op1,op2,&*psum,&*pdiff);
}
void sum_diff(float op1,float op2,float *psum,float *pdiff){
*psum = op1 + op2;
*pdiff = op1 - op2;
}
这个关于指针的错误使用的例子,大家可以自己看看都有哪些错误。
函数的指针传参
必须使用指针传参
首先,我们来看这样的一个函数:
void swap(int *numa,int *numb);
这个函数的目标是:对于传入的两个数,对他们进行交换。根据之前学习到的知识,想要交换两个数,是很容易实现的:
int temp;
temp = numb;
numb = numa;
numa = temp;
现在,开始讨论这个函数,思考为什么需要传入指针的一种情况:
// 现在假设函数的原型是
void swap(int numa,int numb);
首先,需要大家有这样的一个意识: 函数传参,传递的都是一个数值
。这个概念的理解请不要偏颇,这里的数值的含义较为狭窄:就是一个数。(这句话是不是要单独开一个博文写写呢?)
比如,对于swap
函数,如果是下面的方式进行调用:
int a = 3,b = 5;
swap(a,b); // swap(3,5);
在这里,对函数传入参数a
和b
,和后面的注释中那样传递入3和5是没有本质的差别的。而根据前面的学习,大家可以知道,字面常量是无法存储数据的,所以函数中的交换操作自然无法达成。
而对于swap
函数的形参是指针的情况,因为传入的是地址这个“常量”,最终在函数内部需要利用解引用符号找到对应的内存空间,所以能够实现数据的交换。
数组只能使用指针传参
另一种需要传递指针的情况就是数组了,之前在学习中大家也写过几个相关的例子,同时也知道了一般在向函数传递数组的时候,还需要跟随一个数组的长度值。
为了减小传参的体积
之前大家简单的学习了结构体的相关知识。在写代码的时候,结构体中的变量可能并不多,但是大家考虑一个有100个变量的结构体,是不是意味着需要将这100个变量的值都赋值给函数呢。如此,内存开销势必增加。所以对于这样的情况,也会传递给函数结构体的指针。之所以结构体能够传递指针,是因为结构体有一个性质和数组十分类似:它在内存中也是连续存储的(严格来说结构体本身是可能存在空隙的,但是总的来说它还是连续的)。
作业成绩统计
编号 | 学号 | Cnblogs昵称 | 代码 | 总结 | 抄袭行数 | 加权得分 | 备注 |
---|---|---|---|---|---|---|---|
1 | 160809401 | 付胤 | 70 | 70 | 52 | 38.8 | 代码有一题没有做 |
2 | 160809402 | 张博洋 | 0 | 0 | 0 | 0 | 完全看不懂写了些什么 |
3 | 160809403 | 董宇豪 | 85 | 50 | 23 | 57.2 | 最后一个代码没有写成一个函数 |
4 | 160809404 | 朱念齐 | -100 | -100 | 0 | -100 | |
5 | 160809405 | 芦彦儒 | -100 | -100 | 0 | -100 | |
6 | 160809406 | ------ | ------ | ------ | ------ | ------ | ------ |
7 | 160809407 | Leonardo#* | -100 | -100 | 0 | -100 | |
8 | 160809408 | iL.linker | 50 | 80 | 34 | 41.6 | 第三题没有写,第二题代码有误 |
9 | 160809409 | gdcs16_409 | 85 | 90 | 82 | 37.8 | |
10 | 160809410 | 无声的梦 | 90 | 90 | 0 | 90 | |
11 | 160809411 | 刘悦 | -100 | -100 | 0 | -100 | |
12 | 160809412 | 张磊 | -100 | 80 | 0 | -28 | |
13 | 160809413 | 王洪烨 | 90 | 65 | 89 | 26.6 | 作业明显没有之前认真 |
14 | 160809414 | 纪柏如 | 70 | 80 | 20 | 62 | |
15 | 160809415 | 闫墨杰 | -100 | -100 | 0 | -100 | |
16 | 160809416 | 史航 | 70 | 90 | 49 | 48.6 | |
17 | 160809417 | 狂欢 | -100 | -100 | 0 | -100 | |
18 | 160809418 | 水母Jam | 85 | 75 | 92 | 25.8 | 代码稍有错误 |
19 | 160809419 | 朱钰铖 | -100 | -100 | 0 | -100 | |
20 | 160809420 | 虞小生 | 70 | 85 | 21 | 63.4 | |
21 | 160809421 | 饮冰少年1 | 90 | 60 | 39 | 54.6 | |
22 | 160809422 | ----------- | ------ | ------ | ------ | ------ | ------ |
23 | 160809423 | 李筱 | -100 | -100 | 0 | -100 | |
24 | 160809424 | Xzy! | 70 | 60 | 46 | 38.4 | |
25 | 160809425 | 刹那神华 | -100 | 50 | 0 | -40 | 没有找到代码 |
26 | 160809426 | zlt.Santorini'Ly | 85 | 85 | 92 | 29.8 | |
27 | 160809427 | 江超民 | 85 | 65 | 83 | 27.2 | |
28 | 160809428 | zxkai | 85 | 60 | 83 | 25.2 | 勇于承认抄袭“第三题实在不会 复制了同学的” |
29 | 160809429 | 王鑫沐 | 75 | 85 | 80 | 31 | |
30 | 160809430 | 茉妍 | 75 | 70 | 80 | 25 | |
31 | 160809431 | 茉莉雨 | 85 | 90 | 0 | 87 |