函数:function 方法
一段具有某项功能的代码的集合,是C语言中管理代码的最小单位
把代码封装成一个个的函数,是为了方便管理和调用代码。
函数的分类:
标准库函数:
C语言标准委员会为C语言以函数形式提供的一些基础的功能,被封装在libc.so库中,使用时需要包含头文件,只需要 函数名(参数) 调用即可。
系统函数:(不是函数)
是操作系统以函数接口形式提供的一些功能,这些功能包括:
内存管理、信号处理、文件IO、文件管理、进程管理、进程通信、线程通信、线程同步、网络通信
第三方库函数:
glog 日志记录
md5 密码验证
JSON 序列化和反序列化
自定义函数:
为了更好的管理代码、减少冗余,把代码封装成函数形式
注意:一个函数尽量不超过50行,一个函数负责一个功能
函数声明:函数声明的目的是为了告诉其他的代码使用者函数的调用形式
返回值类型 函数名(类型1 变量1,类型2 变量2,…);
1、C语言中函数名一般全部小写,用下划线分隔(sum_int)
2、如果不需要参数建议写void,不要空着
3、如果不需要返回值,也写void
隐式声明:当调用函数时没有定义,就会产生隐式声明,编译器会猜测函数的格式,返回值会 猜测成int类型,参数列表会根据调用时提供的参数来猜测。
函数定义:
返回值类型 函数名(类型1 变量1,类型2 变量2,…);
{
函数体
return val;
}
注意:如果定义写在调用之前,函数声明可以省略。
函数调用:
函数名(实参);
返回值放在调用时的位置,可以立即使用,也可以用变量来记录下来
练习:获取10个范围是[100,1000]的随机数
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(int argc,const char* argv[])
{
srand(time(NULL));
int n;
for(int i = 0;i < 10;i++)
{
n = rand() % 901 + 100;
printf("%d\n",n);
}
}
运算符优先级:
单目、算数、位、关系、逻辑、三目
函数传参:
- 形参变量属于它所在的函数,出了该函数就不能使用了
- 实参和形参直接都是以赋值的形式进行数据传递的(值传送)
- return 其实是把返回值数据放置到一个公共区域(函数和函数调用者),如果不写return语句,那么该区域中就是一个随机的垃圾数据。
- 如果数组作为函数的参数传递时,长度会丢失,需要额外增加一个变量把数组的长度也传递过去。
- 函数之间数组的传递是"址传递",函数和函数调用者可以共享数组
值传递:
普通变量单向值传递 函数之间不能共享同名局部变量
址传递:
数组长度会丢失,需要额外增加一个参数传递数组长度,此时该数组就被两个函数共享
返回值:return语句并不是把数据直接传递给调用者,而是把返回值放在一个他们都能访问的公共区域,如果函 数没有return语句,该位置的值就是一个随机的垃圾数据(上上次函数的返回值)
练习:双色球:
6红球:1-33 不重复
1篮球:1-16 不重复
srand(time(NULL));
char red[6] = {},cnt = 0,i = 0;
while(cnt < 6)
{
int num = rand() % 33 + 1;
for(i = 0; i<cnt ;i++)
{
if(num == red[i])
{
break;
}
}
if(i == cnt)
{
red[cnt++] = num;
}
}
我的垃圾代码
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(int argc,const char* argv[])
{
srand(time(NULL));
int arr[6] = {};
arr[0] = rand() % 33 + 1;
int m = 1,cnt = 0;
while(cnt<6)
{
arr[m] = rand() % 33 + 1;
cnt++;
for(int i = 0;i < m;i++)
{
if(arr[m] == arr[i])
{
arr[m] = 0;
cnt--;
m--;
}
}
m++;
}
int l = 0;
l = rand() % 16 +1;
for(int i = 0;i<6;i++)
{
printf("第%d红球为%d\n",i+1,arr[i]);
}
printf("篮球为 %d\n",l);
}
作业:实现一个函数,判断一个整数是否时素数,调用该函数显示出100~10000之间的所有素数。
#include <stdio.h>
#include <stdbool.h>
bool is_su(int num);
int main(int argc,const char* argv[])
{
for(int i = 100;i <= 10000;i++)
{
if(is_su(i))
{
printf("%d\n",i);
}
}
}
bool is_su(int num)
{
int i = 2;
for(i=2;i<num;i++)
{
if(0 == num%i)
{
break;
}
}
return (i >= num);
}
作业:输入两个日期,计算出两个日期之间相隔了多少天?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int days(int year,int month,int day);
int main(int argc,const char* argv[])
{
int year1,month1,day1,days1,days2,year2,month2,day2,day_cha;
printf("请输入一个年份:");
scanf("%d%d%d",&year1,&month1,&day1);
days1 = days(year1,month1,day1);
printf("请输入另一个年份:");
scanf("%d%d%d",&year2,&month2,&day2);
days2 = days(year2,month2,day2);
day_cha =abs(days1 -days2);
printf("%d",day_cha);
return 0;
}
int days(int year,int month,int day)
{
int days = 0;
int arr[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
arr[1] = 28 + (year%4 == 0 && year%100 != 0 ||year %400 ==0);
for(int i = 0;i < month-1;i++)
{
days += arr[i];
}
int cnt = 0;
for(int i = 1;i < year;i++)
{
if((i%4 == 0 && i % 100 != 0 || i % 400 == 0))
{
cnt++;
}
}
days = days + cnt +(year-1)*365 + day - 1;
return days;
}
作业:实现一个函数,判断整数是否是回文数,调用它来显示出1亿到10亿之间的所有回文数
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool is_hui(int n);
int main(int argc,const char* argv[])
{
for(int i = 100000000;i < 1000000000;i++)
{
if(is_hui(i))
{
printf("%d ",i);
}
}
}
bool is_hui(int n)
{
int new = 0;
int old = n;
if(n < 0)
{
return 0;
}
while(old)
{
new = new*10 + old%10;
old /= 10;
}
return (new == n);
}
作业:计算出100的阶乘
#include <stdio.h>
int main(int argc,const char* argv[])
{
// 运算结果按位存到数组中 123 *9
char rets[256] = {1};
// 指向有进位时要赋值的位
int cnt = 1;
for(int i = 2; i<=100; i++)
{
char carry = 0;
for(int j = 0; j<cnt; j++)
{
short num = rets[j] * i + carry;
rets[j] = num % 10;
carry = num / 10;
}
while(carry)
{
// 如果最高位有进位,则赋值给进位,并cnt++
rets[cnt++] = carry % 10;
carry /= 10;
}
}
printf("%d\n",cnt);
while(cnt--)
{
printf("%hhd",rets[cnt]);
}
}
作业:输入一个整数,显示它的补码
#include <stdio.h>
int main(int argc,const char* argv[])
{
int num = 0;
scanf("%d",&num);
char bits[32] = {};
for(int i = 0; i<32; i++)
{
bits[i] = num >> i & 1;
}
for(int i=31; i>=0 ;i--)
{
printf("%hhd",bits[i]);
}
}
练习:实现一个函数,找出数组中的最大值。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int max_arr(int arr[],int len);
int main(int argc,const char* argv[])
{
srand(time(NULL));
int arr[20] = {};
for(int i = 0;i < 20;i++)
{
arr[i] = rand()%1000;
}
printf("%d",max_arr(arr,20));
}
int max_arr(int arr[],int len)
{
int max = arr[0];
for(int i = 1; i < len; i++)
{
if(arr[i]>max)
{
max = arr[i];
}
}
return max;
}
练习:实现一个函数,对数组进行排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void sort_arr(int arr[],int len);
int main(int argc,const char* argv[])
{
srand(time(NULL));
int arr[20] = {};
for(int i = 0;i < 20;i++)
{
arr[i] = rand()%1000;
}
sort_arr(arr,sizeof(arr)/sizeof(arr[0]));
for(int i = 0; i<20;i++)
{
printf("%d ",arr[i]);
}
}
void sort_arr(int arr[],int len)
{
for(int i = 0; i < len-1; i++)
{
for(int j = i+1; j<len;j++)
{
int t = 0;
if(arr[i]>arr[j])
{
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
}
}
练习:实现一个函数,查找数组中是否存在某个值,如果存在则返回该数据在数组中的下标,如果找不到则返回负数
#include <stdio.h>
#include <stdlib.h>
int find_arr(int arr[],int len,int n);
int main(int argc,const char* argv[])
{
int arr[20] = {1,3,5,2,16,35};
printf("%d",find_arr(arr,sizeof(arr)/sizeof(arr[0]),35));
}
int find_arr(int arr[],int len,int n)
{
int i = 0;
for(i = 0; i < len; i++)
{
if(arr[i] == n)
{
break;
}
}
if(i == len)
{
return -1;
}
else
{
return i;
}
}