时间:2022-11-03 10:30:56 | 栏目:C代码 | 点击:次
函数的概念
函数的类型
通过某种规则将 x处理成 y,如: y = 2x +1
(根据数据)执行一系列动作,进而完成某种功能,如:屏幕打印
C语言中函数的组成部分
函数名:函数的唯一标识
函数参数定义:数据输入(数据→数据,数据→动作)
函数返回类型:
广义函数示例:
返回类型 函数名(参数1,参数2)
{
程序语句1;
程序语句2;
......;
程序语句n;
}
C语言中的函数示例

函数的调用
下面看一段函数调用的代码:
#include <stdio.h>
int func_demo( int x )
{
int y = 0;
y = 2 * x - 1;
return y;
}
int main()
{
int r1 = func_demo(1);
int r2 = func_demo(5);
int r3 = func_demo(10);
printf("r1 = %d\n", r1);
printf("r2 = %d\n", r2);
printf("r3 = %d\n", r3);
return 0;
}
下面为输出结果:

下面再看一段编写函数计算累加和的代码:
#include <stdio.h>
int sum (int n)
{
int r = 0;
int i = 0;
for(i=1; i<=n; i++)
{
r += i;
}
return r;
}
int main()
{
int o[10] = {10, 20, 30, 40, 50, 100};
int r[10];
int i = 0;
for(i=0; i<10; i++)
{
r[i] = sum(o[i]);
}
for(i=0; i<10; i++)
{
printf("sum(%d) = %d\n", o[i], r[i]);
}
return 0;
}
下面为输出结果:

采用数组可以便捷的求出从1加到指定的数。
小结
再论C语言程序的入口
深入理解main()
应用程序的运行

应用程序运行流程
下面看一段代码,实际感受一下吧:
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("Hello World!\n");
system("pause");
return 0;
}
没错,就是这个简单的不能再简单的代码,打开Test.exe,得到下图:

下面来证明一下 返回值 0 是返回给操作系统,首先打开命令提示符,如下:

然后在命令提示符上切换到这个目录,采用 cd 命令,如下:

然后运行 Test.exe,如下:

按下回车,输入echo %errorlevel%,如下:

可以看到输出 0 ,这是 main 函数中的返回值。如果把 return 0那里换成 return 666,那么运行 echo %errorlevel% 会输出 666。这就说明返回值成功返回给操作系统。
核心本质
工具包的本质
小结
函数定义与函数调用
函数在被调用前必须完整定义
函数可以先被声明,再被定义
特殊的基础类型
void 深入理解
所以说,下面程序的写法就是错误的。
#include <stdio.h>
void demo(void i)
{
return i;
}
int main()
{
void v;
void x = v;
demo(x);
return 0;
}
注意事项
C语言中的函数如果确定不需要参数,那么用 void 定义参数,而不是不写参数。
#include <stdio.h>
void f( )
{
printf("void f() \n");
}
void g(void)
{
printf("void g() \n");
}
int main()
{
f();
f(1, 2);
g();
// g(1); // ERROR
return 0;
}
下面为输出结果:

可以看出,f 函数的输入参数是没有限制的,而g 函数没有输入参数,这点要特别注意。
关于函数返回
return 语句直接返回主调函数,后续代码不再执行
对于无返回值函数
对于有返回值的函数
小结
深入函数参数
下面看一段代码:
#include <stdio.h>
int test(int n);
int main()
{
int i = 3;
int j = test(i);
printf("i = %d, j = %d\n", i, j);
return 0;
}
int test(int n)
{
n = n * 10;
return n;
}
下面为输出结果:

特殊的数组参数
注意事项
void func (int a[ ]) 等价于void func (int a[1]) 等价于void func (int a[10]) 等价于void func (int a[100])下面看一段代码,加深印象:
#include <stdio.h>
void demo(int a[3])
{
a[0] = 50;
}
int sum(int a[], int len)
{
int ret = 0;
int i = 0;
while( i < len )
{
ret += a[i];
i++;
}
return ret;
}
int main()
{
int arr1[5] = {0, 1, 2, 3, 4}; // arr1[0] -> 0
int arr2[10] = {0, 10, 20, 30, 40}; // arr2[0] -> 0
demo(arr1);
demo(arr2);
printf("arr1[0] = %d\n", arr1[0]);
printf("arr2[0] = %d\n", arr2[0]);
printf("sum(arr1) = %d\n", sum(arr1, 5));
printf("sum(arr2) = %d\n", sum(arr2, 10));
return 0;
}
下面为输出结果:

这里注意一下这句话:在函数内部修改数组形参,将影响数组实参,所以当调用 demo 函数后,实参的 arr1[0] 和 arr2[0] 都变成了50。
小结
排序的一般定义
排序中的关键操作
比较
交换
核心思想
解决方案
编写函数 int Min(int a[], int b, int e) 选择最小元素
循环遍历数组,将每次找到的最小元素交换就位
下面看一下示例代码:
#include <stdio.h>
int Min(int a[], int b, int e)
{
int r = b;
int i = 0;
for(i=b; i<=e; i++)
if( a[r] > a[i] )
r = i;
return r;
}
void Sort(int a[], int n)
{
int i = 0;
int j = 0;
int k = 0;
for(i=0; i<n; i++)
{
j = Min(a, i, n-1);
if( i != j )
{
k = a[i];
a[i] = a[j];
a[j] = k;
}
}
}
void Print(int a[], int n)
{
int i = 0;
while( i < n )
printf("%d ", a[i++]);
printf("\n");
}
int main()
{
int a[5] = {20, 30, 10, 40, 50};
printf("Origin: \n");
Print(a, 5);
Sort(a, 5);
printf("After: \n");
Print(a, 5);
return 0;
}
下面为输出结果:

小结
C语言中变量的分类
局部变量
全局变量
同名变量的问题
同名变量规则
下面看一段代码,感受一下:
#include <stdio.h>
int var = 100; // 全局变量
void f(int var) // var <==> 局部变量
{
var++;
printf("var = %d\n", var);
}
int main()
{
int var = 10; // 局部变量
f(var); // f(10);
printf("var = %d\n", var); // var = 10;
return 0;
}
下面为输出结果:

变量的作用域
局部变量的作用域
全局变量的作用域
下面看一段代码,感受一下:
#include <stdio.h>
int var = 100; // 全局变量
int main()
{
int var = 10; // 局部变量
{
int var = 1; // 局部变量
printf("var = %d\n", var);
}
printf("var = %d\n", var); // var = 10;
return 0;
}
下面为输出结果:

注意:存在多个同名变量时,优先使用最近定义的变量
小结
不同变量的物理存储区域
生命期:变量从创建到销毁的时间(即:合法可用的时间)
不同变量的生命期
全局数据区中的变量
栈空间中的变量
局部变量在函数调用返回后销毁
下面看一段代码,感受一下变量生命期:
#include <stdio.h>
int var = 1;
void func()
{
printf("var = %d\n", var);
}
int main()
{
int var = 2;
int i = 0;
for(i=0; i<5; i++)
{
int var = 4;
var += i;
printf("var = %d\n", var);
}
func();
printf("var = %d\n", var);
return 0;
}
下面为输出结果:

这个例子充分展示了变量的生命周期,值得仔细体会。
作用域与生命期无本质联系
作用域规则是语法层面对变量是否可访问的规定
生命期是二进制层面上变量存在于内存中的时间
可能的情况
静态变量
???????变量的生命期由变量存储位置决定 ???????
不同类型变量示例??????????????
#include <stdio.h>
int g_var = 1;
static int g_sVar = 2;
int main()
{
static int s_var = 3;
auto int v = 4;
register int rv = 5;
printf("g_var = %d\n", g_var);
printf("g_sVar = %d\n", g_sVar);
printf("s_var = %d\n", s_var);
printf("v = %d\n", v);
printf("rv = %d\n", rv);
return 0;
}
下面为输出结果:

下面看一段代码,感受一下 static 关键词:
#include <stdio.h>
int global;
int func(int x)
{
static int s_var; // 全局数据区中的变量,默认初始化为 0
// 并且,只做一次初始化
s_var += x;
return s_var;
}
int main()
{
int i = 0;
for(i=1; i<=5; i++)
{
printf("func(%d) = %d\n", i, func(i));
}
printf("func(0) = %d\n", func(0));
printf("global = %d\n", global);
return 0;
}
下面为输出结果:

这里注意:全局数据区中的变量,默认初始化为 0 ,并且,只做一次初始化
小结
| static | auto(默认) | register | |
| 局部变量 | 全局数据区 | 栈空间 | 寄存器(可能) |
| 全局变量 | 全局数据区 | --- | --- |
题目:编写函数,将字符串转换为整型数
函数原型:int str2int(char s[]);
参数:可以代表整型数的字符串
返回值:整型值
注意事项:
算法流程

上代码:
#include <stdio.h>
int getNumber(char c)
{
int ret = -1;
if( ('0' <= c) && (c <= '9') )
ret = c - '0';
return ret;
}
int str2int(char str[])
{
int ret = 0;
int sign = 0;
int i = 0;
if( getNumber(str[0]) != -1 )
{
sign = 1;
i = 0;
}
else if( str[0] == '+' )
{
sign = 1;
i = 1;
}
else if( str[0] == '-' )
{
sign = -1;
i = 1;
}
while( sign && str[i] )
{
int n = getNumber(str[i]);
if( n != -1 )
ret = ret * 10 + n;
else
break;
i++;
}
ret = sign * ret;
return ret;
}
int main()
{
printf("%d\n", str2int("123"));
printf("%d\n", str2int("-12345"));
printf("%d\n", str2int("567xyz89"));
printf("%d\n", str2int("abc"));
printf("%d\n", str2int("-xyz"));
return 0;
}
下面为输出结果:

在程序设计中,将函数自调用称为递归调用
递归是一种数学上分而自治的思想 ???????
递归模型的一般表示法

递归在程序设计中的应用
递归函数
递归思想的应用:?????????????
自然数列求和:sum( n ) = 1 +2 +3 + ... + n??????

斐波拉契数列:1,1,2,3,5,8,13,21,...

上代码:
#include <stdio.h>
int sum(int n)
{
int ret = 0;
if( n == 1 )
ret = 1;
else
ret = n + sum(n-1);
return ret;
}
int fac(int n)
{
int ret = 0;
if( n == 1 )
ret = 1;
else if( n == 2 )
ret = 1;
else if( n >= 3 )
ret = fac(n-1) + fac(n-2);
else
ret = -1;
return ret;
}
int main()
{
int i = 0;
printf("sum(1) = %d\n", sum(1));
printf("sum(10) = %d\n", sum(10));
printf("sum(100) = %d\n", sum(100));
for(i=1; i<=10; i++)
{
printf("%d, ", fac(i));
}
printf("\n");
return 0;
}
下面为输出结果:

小结