函数与宏

18 篇文章 0 订阅
一、函数
1.函数定义:就是函数体的实现。函数体就是⼀个代码块。他在函数被调⽤的时候执行。
2。函数声明(函数原型):函数声明出现在函数被调用的地方。函数声明向编译器提供函数的相关信。用于函数被正确的调用。
函数包括:类型,函数名(),代码块
int fun()
{
  printf("hello world ");
return 0;
}
return 语句
1.表明函数正确执行到函数调用的地方
2.允许函数任意位置返回;
3.如果函数不需要返回值,则函数类型定义为void;
3.函数声明:
1.函数原型一般写在.h文件中
2.如果函数没有返回值,则缺省的情况为整形
如递归实现n的阶乘;
首先明白要明白递归的条件:
1. 存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。
2. 每次递归调⽤之后越来越接近这个限制条件。
原理很简单就是自己调用自己,这样有个好处是逻辑都是一样的的,而且会使问题的规模变小,就是到达那个限制条件。
i
nt mypow(n, k)
{
	if (k == 0)
	{
		return 1;
	}
	return n*mypow(n, k-1);


}
int main()
{
	int n ;
	int k  =0;
	printf("please enter:<n,k>\n");
	scanf("%d %d", &n,&k);
	int ret = mypow(n, k);
	printf("%d", ret);
	system("pause");
	return 0;
}
这样我们再来分析,当K为0的时候就是它的限定条件;每一次调用函数都更加接近k为0的情况。
我们称k为0的情况为递归出口。
二、可变参数列表
在函数原型中,列出函数可接受的参数,但原型只能显示固定的数目的参数,让一个函数接受不同数目的参数可不可以呢?答案是肯定的,只有有些限制。如求指定数目的平均值:如
int average(int value, ...)
{
	va_list arg;//定义变量;
	int count = 0;
	float sum = 0;
	va_start(arg, value);
	{
		for (; count < value; count++)
		{
			sum += va_arg(arg, int);
		}
	}//对参数作为准备;
	va_end (arg);
	return sum / value;
}
int main()
{
	float ret = average(4, 4, 5, 6, 7);
	printf("%f\n", ret);
	system("pause");
	return 0;
}
value 是数据总数,可变参数第一个参数必须是明确的;后面表示参数;va_start和va_end用来传递参数;va_arg接受两个参数,第一个是va_list的变量;第二个是要访问数据的类型;va_arg提取所有数据;
在MSDN的原型为:
#include<stdarg>type va_arg(va_list argptr,type);
void va_start(va_list argptr,list_parm);
void va_end(va_list argptr);
功能:
宏va_arg()用于给参数传递可变长度的参数列表。
1.首先,必须调用va_start()传递有效的参数列表va_list和函数强制的第一个参数。 第一个参数代表将要传递的参数的个数。
2.其次,调用va_arg( )传递参数列表va_list和将返回的参数的类型。va_arg()的返回值是当前的参数。
3.再次,对所有的参数重复调用va_arg()
4.最后,调用va_end()传递va_list对完成后的清除是必须的。
三、printf函数的实现:
define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include <stdarg.h> 
#include<assert.h>
int my_printf(const char*format, ...)
{
	assert(format);
	va_list arg_list;
	va_start(arg_list, format);
	int count = 0;
	const char*start = format;
	while (*start != '\0')
	{
		if (*start == '%')
		{
			start++;
			switch (*start)
			{
			case 'd':
			{
						int _int = va_arg(arg_list, int);
						char buf[10];
						_itoa(_int, buf, 10);
						fputs(buf, stdout);
						count += strlen(buf);
			
			}
				break;
			case's':
			{
					   char*_str = va_arg(arg_list, char*);
					   fputs(_str, stdout);
					   count += strlen(_str);
			}
				break;
			case'f':
			{
					   char double_f = va_arg(arg_list, double);
					   printf("%lf", double_f);
			}
				break;
			case'c':
			{
					   char _c = va_arg(arg_list, char);
					   putchar(_c);
					   count++;
			}
				break;
			default:
				break;
			}
			start++;
			continue;
		}
		putchar(*start);
		start++;
		count++;
	}
	va_end(arg_list);
	return count;
}
int main(int argc, char *argv[])
{
	int i = 0;
	for (; i < argc; i++)
	{
		printf("%s\n", argv[i]);
	}
	int ret = my_printf("hello %s:\n%d:\n %f:\n %c\n", "world", 10, 3.14,'o');
	my_printf("count:%d\n", ret);
	system("pause");
	return 0;
}
四、宏
#define机制中,允许把参数替换到文本中,我们称为宏。
宏的声明方式:
#define name (parmerter_list) stuff
parmerter_list表示是参数列表一般表示参数列表。与name 紧邻
可以用宏替换在文本中出现的任何位置如:
#define SQUARE(x) x*x;
SQUARE(5)
很容易得到它的值是
25
如果这样呢
a = 5;
printf("%d",SQUARE(a+1))
它的值回事36 吗?实际上是11,它的顺序应该是这样的,a*a+1;如果还想得到一个正确的结果那么必须是加上()就可以了。
#define SQUARE(x) ( x)*(x)
宏的缺陷是可能会修改变量:
#define MAX(a,b)  ((a)>(b)?a:b)
int main()
{
	int a = 5;
	int b = 6;
	int c = 0;
	c = MAX(a++, b++);
	printf("%d %d %d", a,b,c);
	
		system("pause");
		return 0;
}


我们来分析下,首先是执行的表达式的求值,就是a++和b++,这样它的结果是,6和7了,然后再进行宏替换进行两个数大小的比较。第二次的结果是返回值是b++又进行了一次自增的过程。

实际上就是c= ((a++)>(b++)?(a++):(b++))这样结果就一目了然了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值