一、函数的调用
传值调用
:函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。传址调用
:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式;这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。
二、练习
练习一:写一个函数可以判断一个数是不是素数,然后用函数来实现打印100-200之间的素数
#include <stdio.h>
#include <string.h>
#include <math.h>//sqrt函数的使用要引用该头文件
int is_prime(int n)
{
//用2到n-1之间的数字去试除
int j = 0;
//for (j = 2; j < n; j++)
for (j = 2; j <=sqrt(n); j++)//缩小判断范围
{
if (n % j == 0)
return 0;
}
return 1;
}
int main()
{
int i = 0;
int count = 0;
for (i = 100; i <= 200; i++)
{
//判断i是否为素数
if (is_prime(i) == 1)
{
count++;
printf("%d ",i);
}
}
printf("\ncount=%d ",count);
return 0;
}
代码的运行结果如下:
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
count=21
练习二:写一个函数判断一年是不是闰年
int is_runnian(int n)
{
if (n % 4 == 0)
{
if (n % 100 != 0)
return 1;
}
if (n % 400 == 0)
{
return 1;
}
return 0;
}
int main()
{
int year = 0;
printf("请输入要判断的年份:\n");
scanf("%d",&year);
if (is_runnian(year) == 1)
printf("%d年是闰年\n", year);
else
printf("%d年不是闰年\n",year);
return 0;
}
运行结果如下:
请输入要判断的年份:
1000
1000年不是闰年
请输入要判断的年份:
2000
2000年是闰年
打印1000-2000年之间的所有闰年年份并计数
int is_runnian(int n)
//规则:如果判断是闰年就返回1;否则就返回0
{
if (n % 4 == 0)
{
if (n % 100 != 0)
return 1;
}
if (n % 400 == 0)
{
return 1;
}
return 0;
}
int main()
{
int year = 0;
int count = 0;
//printf("请输入要判断的年份:\n");
//scanf("%d", &year);
for (year = 1000; year <= 2000; year++)
{
if (is_runnian(year) == 1)
{
count++;
printf("%d ", year);
}
}
printf("\ncount=%d\n",count);
return 0;
}
函数定义里的语句可以简化为:
if((n % 4 == 0 && n % 100 != 0) || (n % 400) == 0 )
return 1;
else
return 0;
或者换成更简单的:
return((n % 4 == 0 && n % 100 !=0) || (n % 400 == 0));
这几种写法都可以,代码的运行结果如下:
1004 1008 1012 1016 1020 1024 1028 1032 1036 1040 1044 1048 1052 1056 1060 1064 1068 1072 1076 1080 1084 1088 1092 1096 1104 1108 1112 1116 1120 1124 1128 1132 1136 1140 1144 1148 1152 1156 1160 1164 1168 1172 1176 1180 1184 1188 1192 1196 1200 1204 1208 1212 1216 1220 1224 1228 1232 1236 1240 1244 1248 1252 1256 1260 1264 1268 1272 1276 1280 1284 1288 1292 1296 1304 1308 1312 1316 1320 1324 1328 1332 1336 1340 1344 1348 1352 1356 1360 1364 1368 1372 1376 1380 1384 1388 1392 1396 1404 1408 1412 1416 1420 1424 1428 1432 1436 1440 1444 1448 1452 1456 1460 1464 1468 1472 1476 1480 1484 1488 1492 1496 1504 1508 1512 1516 1520 1524 1528 1532 1536 1540 1544 1548 1552 1556 1560 1564 1568 1572 1576 1580 1584 1588 1592 1596 1600 1604 1608 1612 1616 1620 1624 1628 1632 1636 1640 1644 1648 1652 1656 1660 1664 1668 1672 1676 1680 1684 1688 1692 1696 1704 1708 1712 1716 1720 1724 1728 1732 1736 1740 1744 1748 1752 1756 1760 1764 1768 1772 1776 1780 1784 1788 1792 1796 1804 1808 1812 1816 1820 1824 1828 1832 1836 1840 1844 1848 1852 1856 1860 1864 1868 1872 1876 1880 1884 1888 1892 1896 1904 1908 1912 1916 1920 1924 1928 1932 1936 1940 1944 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984 1988 1992 1996 2000
count=243
有一点需要注意:如果一个函数不写返回类型,那么就默认它的返回类型为int类型,所以在写函数的时候函数的返回类型一定要写出来,写清楚。还有一点需要注意,函数的返回类型不写和写成void是两码事,void也属于是类型,它是指无类型、空类型的意思,只是不需要返回而已。
练习三:写一个函数,实现一个整型有序数组的二分查找
int binary_search(int a[],int k,int s)
{
int left = 0;
int right = s - 1;
while(left <= right)
{
int mid = (left + right) / 2;
if (a[mid] > k)
{
right = mid - 1;
}
else if (a[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 key = 7;
int sz = sizeof(arr) / sizeof(arr[0]);//40/4=10
//要实现的功能:找到了就返回找到的位置的下标,找不到就返回-1(下标是不可能返回-1的)
int ret = binary_search(arr,key,sz);//在数组arr的这sz个元素里面找到key
if (-1 == ret)
{
printf("找不到\n");
}
else
{
printf("找到了,下标是:%d\n",ret);
}
return 0;
}
代码的运行结果如下:
找到了,下标是:6
将代码中key的值改为17,测试一下代码的运行效果:
找不到
练习四:写一个函数,每调用一次这个函数,就会将num的值增加1
int hanshu(int i)
{
i += 1;
return i;
}
int main()
{
int num = 0;
num = hanshu(num);
printf("num = %d\n",num);
num = hanshu(num);
printf("num = %d\n", num);
num = hanshu(num);
printf("num = %d\n", num);
return 0;
}
程序的运行结果为:
num = 1
num = 2
num = 3
或者将地址给函数传进去
void Add(int* p)
{
(*p)++;
}
int main()
{
int num = 0;
Add(&num);
printf("%d\n",num);//1
Add(&num);
printf("%d\n", num);//2
Add(&num);
printf("%d\n", num);//3
return 0;
}
最重要的一点就是若想要从函数内部改变函数外部的变量的时候,可能要做的一件事情就是使用指针传地址过去。