C语言 --- 函数

发布时间:2024年01月11日

认识函数

//No.1 学会创建函数
函数返回值类型 函数名(函数参数)
{
	//函数体
    return  函数返回值;
}
//没有返回值写void 没有
//没有参数可以不写
void 函数名()  //void 函数名(void)
{
	//没有返回值不代表没有return
    return;	//return可以不写,没有返回值可以写
    //可以结合if语句提前结束函数
    printf("永远不会执行");	
}
//函数返回值类型: 是由return后面值的类型决定
int ReturnInt()
{
	return 1;    
}
double ReturnDouble()
{
	double d=1.11;
    return d;
}
char ReturnChar()
{
	return 'A';    
}
//函数名: 和标识符起名的规则一样
//函数参数
//形参--->创建函数时用的参数(类型修饰的)
//实参--->调用函数时用的参数(没有类型修饰)
int Max(int a,int b)		//形参 int a,int b //int a=1 ,int b=2
{
    return a>b?a:b;
}
//调用函数: 函数名(实参); 	//形参和实参类型必须一致
Max(1,2);			//1,2实参
int a=1,b=3;
Max(a,b);			//a和b叫做实参
//函数调用每一次使用的内存都是不一样
//所有传参的方式都是用赋值的方式传参  Max(1,2)
#include <stdio.h>
//No.1 无参,无返回的函数,用来做效果
//这种效果一般可能需要重复使用
void print() 
{
	//return;  函数遇到这个reutrn就结束
	printf("----------------------\n");
	printf("\t0.退出\n");
	printf("\t1.录入\n");
	printf("\t2.浏览\n");
	printf("----------------------\n");
}
//No.2 带返回值 带参
//用来做数据的加工
//函数处理后结果需要在调用者中使用,可以同函数返回值体现
int Max(int a, int b)    //int a=aa,int b=bb
{
	return a > b ? a : b;//2
}
//拷贝本的问题
void modifyNum(int a)   //int a=num;
{
	a = 1004;			//局部的
	printf("%d\n", a);
}
void printA() 
{
	//a = 0;
}
int main() 
{
	print();  //函数名(参数)		
	print();
	int aa = 1;
	int bb = 2;
	int result=Max(aa, bb);			//函数返回值是函数调用表达式代表值
	//Max(aa, bb) = 101;    		//函数返回值是一个值,不能充当左值
	printf("Max=%d\n", result);
	printf("Max=%d\n", Max(3, 4));	//Max(3, 4)是一个int的值,所以直接打印
	printf("Max=%d\n", Max(Max(5, 6), Max(4, 3)));
	//上面一行等效下面三行
	int first = Max(5, 6);
	int second = Max(4, 3);
	printf("Max=%d\n", Max(first, second));

	//所有传参方式都是赋值方式
	int num = 100;
	modifyNum(num);
	printf("num=%d\n", num);
	//printf("a=%d\n", a);
	return 0;
}

函数传参

#include <stdio.h>
#include <string.h>
//No.1 对于函数的每一个参数自己都要能解释清楚
int Max(int a, int b)	//功能:求最大值,求谁的最大值(a和b的最大)
{
	return a > b ? a : b;
}
//No.2 传一维数组
//数字类的数组必须要传入数组长度
void printArray(int num[], int arrayNum) 
{
	for (int i = 0; i < arrayNum; i++) 
	{
		printf("%d\t", num[i]);
	}
	printf("\n");
}
//void printArray2(int* num, int arrayNum); 和上面写法等效
//字符类的不需要长度,字符串结束标记
//strlen
int my_strlen(char str[])  		 //str="ABC"
{
	int count = 0;
	while (str[count] != '\0')	//str[0]:'A'  str[1]:'B' str[2]:'C'  str[3]:'\0'
		count++;				//count=1     count=2    count=3
	return count;				//count=3
}
//int my_strlne(const char* str);   //const常属性
//No.3 函数调用的时候,形参和实参类型必须一致
//不一致会存在强制类型转换,如果转换不了直接崩掉
void print(int num)  //int num='A';  //int num="ILoveyou";
{
	printf("\nnum=%d\n", num);
}
//No.4 二维数组独有传参方式
//行可以不同,但是列必须相同
void printArray2D(int array[][4], int row, int cols) 
{
	for (int i = 0; i < row; i++) 
	{
		for (int j = 0; j < cols; j++) 
		{
			printf("%d\t", array[i][j]);
		}
		printf("\n");
	}
}
int main() 
{
	Max(3, 4);			//赋值的方式传参
	int array[3] = { 1,2,3 };
	//写一个在函数打印数组
	printArray(array, 3);
	int array2[5] = { 1,2,3,4,5 };
	printArray(array2, 5);
	char str[] = { "ILoveyou" };
	printf("%d\t", my_strlen("ABC"));
	printf("%d\t", my_strlen(str));
	printf("%zd\t", strlen(str));		//zd  ---unsigned int 
	print('A');
	//print("ILoveyou");
	// 希望大家把编译这种提醒当做错误
	// warning C4047: “函数”:“int”与“char [9]”的间接级别不同
	// warning C4024: “print”: 形参和实参 1 的类型不同
	int array2D[3][4] = { {1},{2},{3} };   //其他的值默认初始化为0
	printArray2D(array2D, 3, 4);
	//所有的数组为参数,都是传入数组名

	return 0;
}
#include <stdio.h>
void printData();
void print(int num);		//声明语法不带函数体
//我上可以一般函数实现都是写在上面
int Max(int, int);			//声明函数可以不带形参名
void printA() 
{

}
void printB()
{
	printA();
}
int main()
{
	//error C2371: “print”: 重定义;不同的基类型
	print(34);					//“print”未定义;假设外部返回 int
	printData();

	extern void printMM();		//外部函数,需要声明一下
	//warning C4013: “printMM”未定义;假设外部返回 int
	printMM();
	return 0;
}
void printData() 
{
	print(43);
}
void print(int num)
{
	printf("%d\n", num);
}
int Max(int a, int b) 
{
	return a > b ? a : b;
}

函数调用

  • 普通调用: 函数名(实参) ,保持形参和实参的类型和数目一致即可

  • 嵌套调用

    • 成为一个函数参数

    • 自己调用自身(递归调用)

      • 退出性条件

      • 推导公式

#include <stdio.h>
int Max(int a, int b) 
{
	return a > b ? a : b;
}
//函数递归-->解决重复有规律的操作问题
//斐波那契数列
//F(1)=1  F(2)=1
//F(3)=F(2)+F(1)=2;
//.....
//F(n)=F(n-1)+F(n-2);
// 1  1  2 3 5 8 13 21
//求解第N项
//考虑数据类型存储范围-->
int F(int n) 
{
	if (n == 1 || n == 2)			//退出性条件
		return 1;
	//printf("%d\n", n);			//n
	return F(n - 1) + F(n - 2);	    //递归
	//递归的本质是通过参数的递归实现递归
	//参数的递归一定是往退出性条件靠拢
	//堆栈溢出-->死递归
	printf("%d\n", n);			    //没有用
}
//汉诺塔问题-->不做要求
int main() 
{
	printf("%d\n", Max(Max(1, 2), Max(3, 4)));
	printf("%d\n", F(8));
	return 0;
}

标准库中一些函数

  • printf和scanf返回值

  • 随机函数

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() 
{
	//srand()函数: 用来设置随机的范围
	//time(NULL); 获取时间戳: 当前离1970年有多少秒->一直改变
	//随机函数种子
	srand((unsigned int)time(NULL)); //把time(NULL)返回值强制转换为无符号整形
	printf("伪随机数:%d\n", rand());  //rand()产生一个值
	//随机数范围
	//rand() 产生x 不知道是多少
	//x%n    [0,n-1]
	int randNum = rand()%10;        //[0-9]
	printf("randNum=%d\n", randNum);
	//x%n+a  [0+a,n-1+a];		    //不从0开始
	randNum = rand() % 10 + 1;      //[1-10]
	printf("randNum=%d\n", randNum);
	//怎么描述概率问题
	int count = 1;
	while (1)
	{
		int num = rand() % 100;		//100个数字 
		printf("第[%d]抽奖:", count++);
		if (num == 0&&count>=200)
		{
			printf("一等奖\n");
			break;
		}
		else if (num >= 1 && num <= 10)
		{
			printf("二等奖\n");     //10/100
		}
		else 
		{
			printf("安慰奖\n");
		}
	}
	int result = printf("ILoveyou\n");	//prinf返回是打印数据的个数
	printf("%d\n", result);
	int num = scanf_s("%d", &result);   //输入成功数据个数
	printf("%d\n", num);
	//while (scanf_s("%d", &num) != 0);
	//随机数
	return 0;
}
文章来源:https://blog.csdn.net/weixin_60569662/article/details/135536498
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。