函数基础知识

1. 函数是什么?

函数(子程序):

  1. 是一个大型程序中的某部分代码, 由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性;
  2. 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

2. 库函数

  1. 为什么有库函数(效率高,稳定性好)
    为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。
  2. c语言常用的库函数
    IO函数、字符串操作函数、字符操作函数、内存操作函数、时间/日期函数、数学函数、其他库函数
  3. strcpy和memset

strcpy(字符串拷贝)

char * strcpy(char * destination, const char * source );
 

memset(对指定内存进行设置,在进行空间初始化或者设置时,只关心内存,不关心类型;设置时以字节为单位)

void * memset ( void * ptr, int value, size_t num );

这里说一下:
void (空类型;不能定义变量,因为其字节大小不明确)
void *(类型明确,指针类型,可以定义变量,void *x;*x不能被解引用,void可以用来接受任意类型,常用于接受指针类型)void * 可以设定成通用接口
注:使用库函数,必须包含#include对应的头文件。

3. 自定义函数

1:自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间;
2:自定义函数名最好见名知意;返回值得写,不然默认整型;
3:具有一定的独立性;

//自定义函数组成:
ret_type fun_name(para1, * )//返回类型 函数名(函数参数, *)
{
statement;//语句项
}
//例如:写一个函数找出两个整数的最大值
#include<stdio.h>
int get_max(int x,int y)
{
return(x>y)?(x):(y)}
int main()
{
int num1=10;
int num2=20;
int max=get_max(num1,num2);
peintf("max=%d\n",max);
return 0;
}

4. 函数参数

实际参数(实参):
真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。再进行函数调用时,他们都有必须有确定的值。
形式参数(形参):
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形参再函数调用完被释放,即只在本函数内有效。

例如:

#include <stdio.h>
void Swap1(int x, int y)//这里的x,y为形式参数
{
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
int main()
{
int num1 = 1;//这里的num1、num2是实际参数
int num2 = 2;
Swap1(num1, num2);
printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
return 0;
}

5. 函数调用

1 . 要发生形参实例化
在函数调用时候,形参会发生实例化,实例化相当于实参的一份临时拷贝
2 . 形参实例化时间:函数调用后,代码执行之前;
3. 函数传参必定形成临时变量(指针变量也是变量);
4. 注意传值传参传址传参(都定义临时变量);

6. 函数的嵌套调用和链式访问

嵌套调用:

#include <stdio.h>
void new_line()
{
printf("hehe\n");
}
void three_line()
{
  int i = 0;
for(i=0; i<3; i++)
 {
    new_line();
 }
}
int main()//相当于调B函数,但是B中有A函数,在执行B时候就会同时调用A函数。
{
three_line();
return 0;
}

链式访问:
把一个函数的返回值作为另外一个函数的参数。

printf返回值是往显示器上显示的(打印的)字符的个数
int num=printf(" aa:%d\n,123 ")  //其结果为7,%d替换为123再计算个数
printf(" \nnum=%d\n, num ")
printf("%d", printf("%d", printf("%d", 43))); //其结果为4321;

拼接:
stract(目标串,要拼接的内容);

7. 函数的声明和定义

声明:

  1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,无关
    紧要。
  2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
  3. 函数的声明一般要放在头文件中的。
    定义:
    函数的定义是指函数的具体实现,交待函数的功能实现。(定义必须包含函数体)test.c防止函数的声明,test.h放置函数体。(多文件)
#//预处理
#pragma once//(防止头文件被重复包含的第一种方法)
#ifndef __TEST_H__ //(防止头文件被重复包含第二种方法)
#define __TEST_H__

8. 函数递归

  1. 什么是递归?
    程序调用自身的编程技巧称为递归。其主要思考方式在于大事化小,即将一些复杂程序拆解成与原程序相似的规模较小的子问题来求解。对于一些问题,可大大减少程序的代码量。
  2. 递归的两个必要条件
    a: 存在限制条件,当满足这个限制条件的时候,递归便不再继续。(递归的出口)
    b: 每次递归调用之后越来越接近这个限制条件。(子问题如何解决)
    举例:
//接受一个整型值(无符号),按照顺序打印它的每一位。
// 例如: 输入:1234,输出 1 2 3 4.
#include <stdio.h>
void print(int n)
{
if(n>9)
{
print(n/10);//由于返回值为整型,所以在循环时 1234/10 结果为123...如此循环
}
printf("%d ", n%10);
}
int main()
{
int num = 1234;
print(num);
return 0;
}

栈溢出:
在某些函数体中,由于循环次数过多或者出现了死循环,这样就有可能导致一直开辟空间,最终导致产生栈空间耗尽的情况,这样的现象我们称为栈溢出。
例如:

//求第n个斐波那契数。
#include<stdio.h>
int fib(int n)
{
if (n <= 2)    
return 1;
  else
  return fib(n - 1) + fib(n - 2);
}
int main()
{
int n=5;
fib(n);
printf("%d ",fib(n));
return 0;
}

上述代码如果将n换为较大一点的,如50,则会在运行时发现运行速度会非常慢。这是因为参数较大,进行了许多重复的计算。这时可以尝试将递归改为非递归。
斐波那契数写成迭代版本:

#include<stdio.h>
int fib_1(int n)
{
	int first = 1;
	int second = 1;
	int third = 1;
	while(n > 2){
		third = first + second;
		first = second;
		second = third;
		n--;
	}
	return third;
}
int main()
{
	int n = 5;
	int res = fib_(n);
	printf("%d\n", res);
	system("pause");
	return 0;
}

可以发现这个代码相对于递归来说,运行速度更快。
总结:

  1. 多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。
  2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。
  3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。

注:各位读者阅读完本文,如果对你有所帮助,还请一键三连哦!如果文章有不妥之处,欢迎在下方评论指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值