C语言--函数

函数的定义和声明

返回类型 函数名(数据类型 形式参数,…)
{
}
1.可以定义在main后面,也可以前面
2.只有main函数调用时,函数才会执行

1.形参和实参的概念

形参(也叫形式参数)
在定义函数名和函数体的时候使用的参数,他没有数据,可以看做一个占位符,只能等到函数被调用时接收传递进来的数据,所以称为形式参数;
实参(也叫实际参数)
在调用时传递给函数的参数,即传递给被调用函数的值,会被被调用函数内部使用,所以称为实际参数;

2.形参和实参的区别与联系
形参和实参的区别:
1):
形参变量在函数未被调用时是不占内存空间的,只有在函数被调用时才会给其分配内存空间,调用结束后内存被回收,所以形参只作用于被调函数内部;
实参是开辟了空间了的,并存储了数据;
2):
形参只能是变量并且必须指定其类型;
实参可以是常量,变量,表达式或者函数等;
3):
形参没有确定的值;
实参在进行函数调用时须具有确定的值,以便把这些值传送给形参;
4):
在一般传值调用的机制中只能把实参传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参值发生改变,而实参中的值不会变化。
在引用调用的机制当中是将实参引用的地址传递给了形参,所以任何发生在形参上的改变实际上也发生在实参变量上。
形参和实参之间的联系:
1):形参和实参在类型上,数量上,循序上必须一致;

RG:F(x)=x*x

#include<stdio.h>
int f(int x){
	x=x*x;
	return x;
} 
int main(void){
	int a=5,b;
	b=f(a);
	printf("a=%d,b=%d",a,b);
	return 0;
}

试一试做一下水仙花数

#include<stdio.h>
int judge(int n){
	int a,b,c;
	a=n/100;
	b=(n/10)%10;
	c=n%10;
	if(a*a*a+b*b*b+c*c*c==n) return 1;
	return 0;
}
int main(void){
	int i;
	for(i=100;i<=999;i++){
		if(judge(i)==1)
		printf("%d\n",i);
	}
	return 0;
}
	
  • 形式参数与实际参数之间是单向值传递

  • 在函数内对形式参数的修改不会影响main 函数内的实际参数

  • 返回类型为void时,没有return语句

  • 对函数类型未加说明,函数的隐含类型为int

#include<stdio.h>
int fun3(int x){ 
	static int a=3;                //  static:保存上一个a的值 
	a=a+x;
	return a;
	
}
int main (void){
	int k=2,m=1,n;
	n=fun3(k);                   // n=3+2=5    a=5
	n=fun3(m);                   //n=5+1=6      a=6
	printf("%d\n",n);
	return 0;
}

题目:输出100以内的素数

#include<stdio.h>
int prime(int n){
	int i;
	for(i=2;i<n;i++){
		if(n%i==0)
		return 0;
	}
	return 1;
}
int main(void){
	int i;
	for(i=2;i<100;i++){
		if(prime(i)==1)
		printf("%d\n",i);
	}
	return 0;
}
  • main函数可以调用其他函数,不能被调用
  • 函数定义不允许嵌套,调用允许嵌套

函数的递归(调用它本身)

题目:求斐波那契数列

#include<stdio.h>
long f(int n){
	long s;
	if(n==1||n==2) return 1;
	s=f(n-1)+f(n-2);
	return s;
}
int main(void){
	int n;
	printf("please input n:");
	scanf("%d",&n);
	if(n<0)
	   printf("error!\n");
	else
	   printf("第%d项斐波那契数列的值是%ld",n,f(n));
	return 0;
}

1、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输人。

#include<stdio.h>

//最大公约数  最大公约数找出两数中的最小值,然后直接相模,当能够同时被两数整除时,则为最大公约数。
size_t GCD(size_t a, size_t b)
{      
	
	size_t gcd;      
	gcd = a > b ? b : a;
	while(gcd > 1)  
	{
		if((a % gcd == 0) && (b % gcd == 0))   
			return gcd; 
		gcd--; 
	}
	return gcd;
}

//最小公倍数
size_t LCM(size_t a, size_t b)
{
	size_t lcm;
	lcm = a > b ? a : b;
	while(1)
	{
		if((lcm % a==0) && (lcm % b==0))
			break;
		lcm++;
	}
	return lcm;
}

int main()
{
	size_t a, b, result;
	printf("请输入两个整数:>");
	scanf("%d %d", &a, &b);

	result = GCD(a, b);
	printf("%d和%d的最大公约数为:%d\n", a, b, result);
	result = LCM(a, b);
	printf("%d和%d的最小公倍数为:%d\n", a, b, result);

	return 0;
}

  • 写一个判素数的函数,在主函数输人一个整数,输出是否为素数的信息
#include<stdio.h>
#include<stdbool.h>

bool IsPrime(int value)     //使用了<stdbool.h>后,可使用true和false来表示真假。
{
	for(int i=2; i<value/2; ++i)
	{
		if(value % i == 0) //说明除了1和本身之外,还能被其他数整除
			return false;
	}
	return true;
}

int main()
{
	int value;
	bool flag;
	printf("请输入 value :>");
	scanf("%d", &value);
	
	flag = IsPrime(value);
	if(flag)
		printf("%d 是素数.\n", value);
	else
		printf("%d 不是素数.\n", value);

	return 0;
}

  • 写一个函数,使给定的一个3X3的二维整型数组转置,即行列互换

关键在于数组互换的表达式 ar[i] [j] = ar[j] [i];其次在循环的时候,内层循环不能到达最大列,需要根据此时是第几行的交换来决定循环的次数,否则有可能数组行列交换之后最后又交换回原来的形状了。

#include<stdio.h>

void PrintArray(int ar[3][3])
{
	for(int i=0; i<3; ++i)
	{
		for(int j=0; j<3; ++j)
		{
			printf("%d ", ar[i][j]);
		}
		printf("\n");
	}
}

void ReverseArray(int ar[3][3])
{
	int tmp;
	for(int i=0; i<3; ++i)
	{
		for(int j=0; j<i; ++j)
		{
			if(i != j) //中间数不发生变化
			{
				//交换两个数
				tmp = ar[i][j];
				ar[i][j] = ar[j][i];
				ar[j][i] = tmp;
			}
			
		}
	}
}

int main()
{
	int array[3][3] = 
	{
		{1,2,3},
		{4,5,6},
		{7,8,9}
	};

	printf("转置前:\n");
	PrintArray(array);

	//进行数组转置
	ReverseArray(array);

	printf("转置后:\n");
	PrintArray(array);

	return 0;
}

  • 写一个函数,使输人的一个字符串按反序存放,在主函数中输入和输出字符串。

要把一个字符串反序存放,其实就是对字符串做一个逆序操作,操作过程为收尾字符交换,直到把所有字符全部交换完毕。

strlen()函数
用法:#include <string.h>
功能:计算字符串s的(unsigned int型)长度
说明:返回s的长度,不包括结束符NULL。

#include<stdio.h>
#include<string.h>
void ReverseString(char str[])
{
	int start, end;
	char tmp;
	start = 0;
	end = strlen(str)-1; //字符数组小标从0开始,所以-1
	while(start < end)
	{
		tmp = str[start];
		str[start] = str[end];
		str[end] = tmp;

		start++;
		end--;
	}
}

int main()
{
	char str[100] = {0};
	printf("请输入一个字符串:>");
	scanf("%s", str);
	printf("原始字符串为:> %s\n", str);
	ReverseString(str);
	printf("反序字符串为:> %s\n", str);
	return 0;
}


  • 写一个函数,将两个字符串连接

利用一个临时数组,空间要保证能够容纳两个字符串,先把第一个字符串进行拷贝到临时数组,第二个字符串在临时数组的尾部接着链接,最后记得加上字符串的结束标记\0即可

#include<stdio.h>

void ConcatStr(char string1[], char string2[], char string[])
{
	int i, j;
	for (i = 0; string1[i] != '\0'; i++)
		string[i] = string1[i];
	
	//找到字符串末尾,继续往后面链接字符串
	for (j = 0; string2[j] != '\0'; j++)
		string[i + j] = string2[j];

	//字符串末尾加上结束符 \0
	string[i + j] = '\0';
}

int main()
{
	char s1[200] = {0}, s2[100]= {0}, s[100] = {0};
	printf("input string1:");
	scanf("%s", s1);
	printf("input string2:");
	scanf("%s", s2);
	ConcatStr(s1, s2, s);
	printf("\nThe new string is %s\n", s);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值