函数的调用:(1)传值调用 (2)传址调用
那我们怎么使用呢?
总结:
(1)传值调用——我们只是把值传过去就可以了,不会涉及形参修改实参的这种方式。
(2)传址调用——当我们在把实参传过去后,形参要能远程找到实参,形参要能修改我的实参,我们这时候就要考虑传址调用了。
实参和形参占用的是不同的内存单元,要使形参能改变我们的实参,就要创造联系。
怎么创造联系呢?如下:
int a=10;
//想把a改为20
(1)
a=20;
(2)
int * pa=&a;//pa就是指针变量,存放a的地址
*pa=20;//*pa解引用操作,*pa就是a
如上:我们想创造联系,就把地址传给实参就行了——这就是传址调用
1.写一个函数可以判断一个数是不是素数。
//写一个函数求100-200之间的素数 #include<stdio.h> #include<math.h>//sqrt的头文件 int is_prime(int x) { //不是返回0 int n = 0; for (n = 2; n <= sqrt(x); n++) { if (x % n == 0) { return 0; } } //是素数返回1 return 1; } int main() { int i = 0; for (i = 100; i <= 200; i++) { //函数判断i是否为素数,是素数返回1,不是返回0 if (is_prime(i) == 1) { printf("%d ", i); } } return 0; }
tip:break与return
break:在循环中的作用是终止循环——一个break跳出一层循环,继续执行后面的代码
return:遇到return函数直接返回了(结束),不管后面还有没有代码都不执行
相比break,return更加直接
2. 写一个函数判断一年是不是闰年。
#include<stdio.h> //判断闰年 //(1)4年一闰,百年不闰 //(2)400年又闰 int is_leap_year(int y) { if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0)) { return 1;//是返回1 } else { return 0;//不是返回0 } } int main() { int y = 0; for (y = 1000; y <= 2000; y++) { //调用函数判断y是否为闰年 //是返回1,不是返回0 if (is_leap_year(y)) { printf("%d ",y); } } return 0; }
注:实参和形参名字可以一样,但是占用的内存单元不一样。
学习好的代码风格,如:
(1)函数名——一定要有意义
(2)写法——要有质量
is_leap_year
IsLeapYear
Is_Leap_Year
前两种都可以,后面不建议
有兴趣的可以去看《高质量的C/C++编程》这本书
3.写一个函数,实现一个整形有序数组的二分查找。
#include<stdio.h> int binary_search(int arr[], int k, int sz) { int left = 0; int right = sz - 1; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] > k) { right = mid - 1; } else if (arr[mid] < k) { left = mid + 1; } else { return mid; } } return -1; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 7;//要查找的数 //调用函数判断是否找到 //找到返回下标 //找不到返回-1 int pos = binary_search(arr, k, 10); if (-1 == pos) { printf("找不到\n"); } else { printf("找到了,下标为%d\n", pos); } return 0; }
那如果数组元素太多,我们怎么算数组的元素个数呢?
#include<stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(arr[0])); return 0; }
sizeof(arr);//这是计算整个数组的大小,单位是字节。
sizeof(arr[0]);//这是在计算数组(第一个)元素的大小,单位是字节。
所以计算数组的元素个数,我们可以:
int sz=sizeof(arr)/sizeof(arr[0]);
4. 写一个函数,每调用一次这个函数,就会将 num 的值增加1。
#include<stdio.h> void Add(int* p) { *p = *p + 1; } int main() { int num = 0; Add(&num); printf("%d\n", num); Add(&num); printf("%d\n", num); Add(&num); printf("%d\n", num); return 0; }
void Add(int* p) { //*p = *p + 1; *p++; } int main() { int num = 0; Add(&num); printf("%d\n", num); Add(&num); printf("%d\n", num); Add(&num); printf("%d\n", num); return 0; }
为什么呢?
操作符的优先级。
改:(*p)++
除了传址调用,我们也可以传值调用如下:
#include<stdio.h> int Add(int n) { return n+1; } int main() { int num = 0; num = Add(num); printf("%d\n", num); num = Add(num); printf("%d\n", num); num = Add(num); printf("%d\n", num); return 0; }