[1]常用内置函数
代码中体现常用的一些库函数:
#if 0
1,输出1-10之间所有整数的平方根和立方
2,产生7个1-31之间的随机数,并且不重复
3,求任意整数的绝对值
4,求任意浮点数的绝对值
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
/*qsort()的自定义比较数据类型*/
int cmp_int(const void* _a, const void* _b)
{
/*强制类型转换*/
int* a = (int*)_a;
int* b = (int*)_b;
return *a - *b;
}
int main(){
double num1 = 0;
int num2 = 0;
for(int i = 1;i <= 10;i++){
/*sqrt()开根号函数,pow()求x的y次方函数,引用头文件math.h,gcc编译要加-lm链接数学库*/
num1 = sqrt(i);
num2 = pow(i,3);
printf("%2d的平方根 = %.2lf,%2d的立方 = %4d\n",i,num1,i,num2);
}
printf("------------------------------------------\n");
int arr[7];
/*srand()播种函数,为了生成不一样的随机数,time(NULL)种子值根据时间播种,头文件stdlib.h和time.h*/
srand(time(NULL));
for(int i = 0,temp;i < 7;i++){
flag:
/*rand()%n+m,生成随机数m到n的随机数,头文件stdlib.h*/
temp = rand()%31+1;
for(int j = 0;j <= i;j++){
if(temp == arr[j]){
goto flag;
}
}
arr[i] = temp;
}
/*qsort()快速排序(quick sort)函数,头文件stdlib.h*/
qsort(arr,7,sizeof(arr[0]),cmp_int);
for(int i = 0;i < 7;i++){
printf("%d ",arr[i]);
}
putchar('\n');
printf("------------------------------------------\n");
int a;
printf("input a int vlaue:");
scanf("%d",&a);
/*abs()整数取绝对值函数,头文件stdlib.h*/
printf("%d的绝对值为:%d\n",a,abs(a));
printf("------------------------------------------\n");
float b;
printf("input a float vlaue:");
scanf("%f",&b);
/*fabs()浮点数取绝对值函数,头文件math.h*/
printf("%.3f的绝对值为:%.3f\n",b,fabs(b));
return 0;
}
运行测试结果:
[2]函数调用
- 定义在其他函数调用前不需要声明;
- 定义在其他函数调用之后,则需要在调用前声明一下。
#include <stdio.h>
#include <stdlib.h>
/*调用前定义的函数,正常调用,无需声明*/
int get_max(int a,int b){
return (a > b) ? a : b;
}
/*函数声明,因为函数的定义在调用后*/
double _pow(double,double);
int main(){
printf("%d\n",get_max(3,2));
printf("%.2lf\n",_pow(2,3));
printf("%.2lf\n",_pow(2,-2));
return 0;
}
double _pow(double a,double b){
double p = 1;
if(b >= 0){
for(int i = 1;i <= (int)b;i++){
p *= a;
}
return p;
}
else{
for(int i = 1;i <= abs(b);i++){
p *= a;
}
return 1/p;
}
}
[3]函数递归
简单的说就是函数自己调用自己,如求1~n整数求和、数的阶乘、斐波那契数列的第n项等等。
/*递归实现1到n的整数求和*/
int sum(int n){
return n==1?1:n+sum(n-1);
}
/*递归实现一个数的阶乘*/
int factorial(int n){
return n==1?1:n*factorial(n-1);
}
/*斐波那契数列第n项*/
int fibonacci(int n){
/*返回数列第n项,当n>2时,递归利用递推关系算出第n项*/
return (n==1||n==2)?1:fibonacci(n-1)+fibonacci(n-2);
}
1>练习一
实现简单的图形面积管理系统
#if 0
(1)显示菜单
欢迎进入图形面积管理系统
1、计算矩形面积
2、计算三角形面积
3、计算圆的面积
0、退出系统
请输入你的选择
(2) 根据菜单进入不同的分支
#endif
#include <stdio.h>
#define PI 3.14
void mainFrame(){
printf("------------------------\n");
printf("欢迎进入图形面积管理系统\n");
printf(" 1.计算矩形面积\n");
printf(" 2.计算三角形面积\n");
printf(" 3.计算圆的面积\n");
printf(" 0.退出系统\n");
printf("------------------------\n");
printf("输入你的选择:");
}
double rectangularArea(double len,double wid){
return len*wid;
}
double triangleArea(double base,double height){
return base*height/2;
}
double circleArea(double r){
return PI*r*r;
}
int main(){
while(1){
mainFrame();
int n;
double length,width,height,base,r;
flag:
scanf("%d",&n);
switch(n){
case 1:
printf("\n-----请输入矩形长宽-----\n");
printf("长 = ");
scanf("%lf",&length);
printf("宽 = ");
scanf("%lf",&width);
printf("矩形面积 = %.2lf\n",rectangularArea(length,width));
break;
case 2:
printf("\n----请输入三角形底高----\n");
printf("底 = ");
scanf("%lf",&base);
printf("高 = ");
scanf("%lf",&height);
printf("三角形面积 = %.2lf\n",triangleArea(base,height));
break;
case 3:
printf("\n-----请输入圆的半径-----\n");
printf("半径 = ");
scanf("%lf",&r);
printf("圆面积 = %.2lf\n",circleArea(r));
break;
case 0:
printf("\n--------系统退出!-------\n");
return 0;
default:
printf("指令错误!请重新输入:");
goto flag;
}
}
return 0;
}
[4]函数传参
1.数值传参
- 将一个实参的值传给另一个形参,函数体修改形参值,实参的值没有改变。
2.地址传参
- 传入参数:将一个实参的地址传给形参指针,函数体对形参指针所指地址赋值,实参的值改变。
- 传出参数:定义一个形参指针,指向要接收结果的实参。
#include <stdio.h>
/*地址传参实现两数交换*/
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
int main(){
int a,b;
scanf("%d %d",&a,&b);
swap(&a,&b);
printf("%d %d\n",a,b);
return 0;
}
3.数组传递
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void print_arr(int arr[],int n){
for(int i = 0;i < n;i++){
printf("%d ",arr[i]);
}
putchar('\n');
}
void create_arr(int arr[],int n){
for(int i = 0;i < n;i++){
arr[i] = rand()%30+1;
}
}
int main(){
srand(time(NULL));
int n;
printf("input arr.length:");
scanf("%d",&n);
int arr[n];
create_arr(arr,n);
print_arr(arr,n);
return 0;
}
1>练习
#if 0
1,设计函数,其功能:求两个浮点数的平均值(传地址方式)
2,设计函数,其功能是:将所有不及格学生的成绩加5分,并求出最终的平均值
3,设计函数,其功能是:将低于平均成绩的学生成绩,放入指定数组中,并返回低于平均成绩的学生个数
4,设计函数,其功能是:求任意一维整型数组的最小值,最大值,最小值下标,最大值下标
5,设计函数,封装冒泡排序函数
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
double f_avg(double *a,double *b){
return (*a+*b)/2;
}
double ch_score(int score[],int n){
double sum = 0;
for(int i =0;i < n;i++){
score[i] = score[i]<60?score[i]+5:score[i];
sum += score[i];
}
return sum/n;
}
int low_score(int arr[],int n,int *p){
int counter = 0;
double avg = 0;
for(int i = 0;i < n;i++){
avg += arr[i];
}
avg /= n;
for(int i = 0;i < n;i++){
if(arr[i] < avg){
*(p++) = arr[i];
counter++;
}
}
return counter;
}
void max_min_Search(int arr[],int n,int *maxVal,int *maxIndex,int *minVal,int *minIndex){
*maxVal = arr[0];
*minVal = arr[0];
for(int i = 0;i < n;i++){
if(arr[i] > *maxVal){
*maxVal = arr[i];
*maxIndex = i;
}
if(arr[i] < *minVal){
*minVal = arr[i];
*minIndex = i;
}
}
}
void bubbleSort(int arr[],int N){
bool flag = false;
for(int i = 0;i < N-1;i++){
for(int j = 0;j < N-i-1;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if(!flag){
break;
}else{
flag = false;
}
}
}
void print_arr(int arr[],int n){
for(int i = 0;i < n;i++){
printf("%d ",arr[i]);
}
putchar('\n');
}
void create_arr(int arr[],int n){
for(int i = 0;i < n;i++){
arr[i] = rand()%100+1;
}
}
int main(){
srand(time(NULL));
printf("--------------1--------------\n");
double a,b;
printf("input 2 double value:\n");
scanf("%lf %lf",&a,&b);
printf("avg = %.2lf\n",f_avg(&a,&b));
printf("--------------2--------------\n");
int s;
printf("input score.length:");
scanf("%d",&s);
int score[s];
create_arr(score,s);
print_arr(score,s);
double avg = ch_score(score,s);
print_arr(score,s);
printf("avgScore = %.2lf\n",avg);
printf("--------------3--------------\n");
int s1;
printf("input score.length:");
scanf("%d",&s1);
int score1[s1];
int lowStu[s1];
create_arr(score1,s1);
print_arr(score1,s1);
int count = low_score(score1,s1,lowStu);
printf("低于平均成绩人数:%d人\n",count);
print_arr(lowStu,count);
printf("--------------4--------------\n");
int n1;
printf("input arr1.length:");
scanf("%d",&n1);
int arr1[n1];
create_arr(arr1,n1);
print_arr(arr1,n1);
int maxVal,minVal,maxIndex = 0,minIndex = 0;
max_min_Search(arr1,n1,&maxVal,&maxIndex,&minVal,&minIndex);
printf("最大值为:%d,下标为%d\n最小值为:%d,下标为%d\n",maxVal,maxIndex,minVal,minIndex);
printf("--------------5--------------\n");
int n;
printf("input arr.length:");
scanf("%d",&n);
int arr[n];
create_arr(arr,n);
print_arr(arr,n);
bubbleSort(arr,n);
print_arr(arr,n);
return 0;
}
[5]函数指针
函数调用方式:
- 直接通过函数名调用
- 通过函数指针回调函数: 函数指针(参数表);
声明: 返回值类型 (*指针名)(参数表);
例如函数:
/*斐波那契数列第n项*/
int fibonacci(int n){
/*返回数列第n项,当n>2时,递归利用递推关系算出第n项*/
return (n==1||n==2)?1:fibonacci(n-1)+fibonacci(n-2);
}
定义函数指针:
int (*ptr)(int) = NULL;
/*指向斐波那契函数*/
ptr = fibonacci;
/*通过指针回调函数*/
//ptr(3);
printf("%d\n",ptr(3)); /*结果为第三项:2*/
1>练习
封装一个既能升序又能降序的冒泡排序函数(函数指针)
#include <stdio.h>
#include <stdbool.h>
/*升序比较规则*/
bool asend(int a,int b){
return a>b?true:false;
}
/*降序比较规则*/
bool desend(int a,int b){
return a<b?true:false;
}
void bubbleSort(int arr[],int N,bool (*ptr)(int,int)){
bool flag = false;
for(int i = 0;i < N-1;i++){
for(int j = 0;j < N-i-1;j++){
if(ptr(arr[j],arr[j+1])){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if(!flag){
break;
}else{
flag = false;
}
}
}
/*下面是测试*/
void print_arr(int arr[],int n){
for(int i = 0;i < n;i++){
printf("%d ",arr[i]);
}
putchar('\n');
}
int main(){
int arr[9] = {7,4,1,8,3,0,4,7,2};
bubbleSort(arr,9,asend);
print_arr(arr,9);
bubbleSort(arr,9,desend);
print_arr(arr,9);
return 0;
}
2>练习
实现数组的增删改查
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void mainFrame(int arr[],int n){
printf("------------------------------\n");
printf("-----------系统数据-----------\n");
for(int i = 0,j = 10;i < n;i++){
if(i == j){
putchar('\n');
j += 10;
}
printf("%2d ",arr[i]);
}
putchar('\n');
printf("------------------------------\n");
printf(" 1.添加数据 \n");
printf(" 2.删除数据 \n");
printf(" 3.修改数据 \n");
printf(" 4.查找数据 \n");
printf(" 0.退出系统 \n");
printf("------------------------------\n");
printf("请输入你的选择:");
}
void insert(int arr[],int n,int insertIndex,int insertVal,int *count){
if(insertIndex >= n){
printf("---------没有该位置!---------\n");
}
for(int i = 0;i < n;i++){
if(i == insertIndex){
if(arr[i] == 0){
*count += 1;
arr[*count-1] = insertVal;
}
else{
for(int j = *count-1;j >= i;j--){
arr[j+1] = arr[j];
}
arr[i] = insertVal;
*count += 1;
}
printf("-----------添加成功!----------\n");
break;
}
}
}
void delete(int arr[],int deleteIndex,int *count){
if(deleteIndex >= *count){
printf("-------该位置没有数据!-------\n");
}
else{
for(int i = 0;i < *count;i++){
if(i == deleteIndex){
for(int j = i;j < *count;j++){
arr[j] = arr[j+1];
}
arr[*count-1] = 0;
*count -= 1;
printf("-----------删除成功!----------\n");
break;
}
}
}
}
void modify(int arr[],int modifyIndex,int modifyVal,int *count){
if(modifyIndex >= *count){
printf("-------该位置没有数据!-------\n");
}
else{
for(int i = 0;i < *count;i++){
if(i == modifyIndex){
arr[i] = modifyVal;
printf("-----------修改成功!----------\n");
break;
}
}
}
}
void search(int arr[],int searchIndex,int *count){
if(searchIndex >= *count){
printf("-------该位置没有数据!-------\n");
}
else{
for(int i = 0;i < *count;i++){
if(i == searchIndex){
printf("查询结果:%d\n",arr[i]);
printf("-----------查询成功!----------\n");
break;
}
}
}
}
void create_arr(int arr[],int N){
for(int i = 0;i < N;i++){
arr[i] = rand()%100 + 1;
}
}
int main(){
srand(time(NULL));
int arr[100] = {0};
/*设置原有数据个数*/
int valueNum = 10;
/*先随机添加10个数据*/
create_arr(arr,valueNum);
while(1){
mainFrame(arr,valueNum);
int insertIndex,insertVal;
int deleteIndex;
int modifyIndex,modifyVal;
int searchIndex;
int order;
flag:
scanf("%d",&order);
while(getchar() != '\n');
switch(order){
case 1:
printf("\n-----------添加数据-----------\n");
printf("添加的位置:");
scanf("%d",&insertIndex);
printf("添加的数据:");
scanf("%d",&insertVal);
insert(arr,100,insertIndex,insertVal,&valueNum);
break;
case 2:
printf("\n-----------删除数据-----------\n");
printf("删除的位置:");
scanf("%d",&deleteIndex);
delete(arr,deleteIndex,&valueNum);
break;
case 3:
printf("\n-----------修改数据-----------\n");
printf("修改的位置:");
scanf("%d",&modifyIndex);
printf("修改成:");
scanf("%d",&modifyVal);
modify(arr,modifyIndex,modifyVal,&valueNum);
break;
case 4:
printf("\n-----------查询数据-----------\n");
printf("查询的位置:");
scanf("%d",&searchIndex);
search(arr,searchIndex,&valueNum);
break;
case 0:
printf("\n-----------系统退出!----------\n");
return 0;
default:
printf("指令错误!请重新输入:");
goto flag;
}
}
return 0;
}
[6]指针函数
- 本质是函数,返回值是指针类型的函数
- 返回值必须为一个有效地址,返回局部变量地址无意义
语法: 类型* 函数名(······){·········}
[7]多文件编程
- 源文件xxxx.c 和头文件xxxx.h
- 一般在项目中,头文件和对应的源文件,文件名相同
- 在项目中其他文件中调用时,要包含对应的.h头文件,编译时要将所有的.c文件一起编译
gcc main.c a.c b.c -o xxx
三、变量
[1]局部变量
- 定义在函数内部的变量
- 生存期:定义------->函数结束
- 作用域:只能在定义的函数内部访问
[2]静态局部变量
关键字: static
- 定义在函数内部的变量,第二次调用函数时,该变量初始值为上一次调用结束时的值
- 生存期:程序开始------->整个程序结束
- 作用域:只能在定义的函数内部访问
- 应用场合:统计数据
[3]全局变量
- 定在本文件中的函数外部
- 生存期:程序开始------->整个程序结束
- 作用域:所有.c文件都可以访问,但是要提前声明
- 声明:加上关键字extern ,如:extern int a;
[4]静态全局变量
关键字: static
- 定在本文件中的函数外部
- 生存期:程序开始------->整个程序结束
- 作用域:仅能在本文件中使用,其他.c文件访问不了