C语言函数及几种作用域不同的变量

[1]常用内置函数

代码中体现常用的一些库函数

#if  0
1,输出1-10之间所有整数的平方根和立方
2,产生71-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   01)显示菜单
       欢迎进入图形面积管理系统
	   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文件访问不了
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值