目录
[一. 函数的参数传递](#一. 函数的参数传递)
[1.1 变量传参](#1.1 变量传参)
[1.2 数组传参](#1.2 数组传参)
[1.3 整型数组的几个练习](#1.3 整型数组的几个练习)
[1.4 字符数组的几个练习](#1.4 字符数组的几个练习)
[二. 函数递归](#二. 函数递归)
[2.1 递归求阶乘](#2.1 递归求阶乘)
[2.2 递归的其他几个练习](#2.2 递归的其他几个练习)
[2.2.1 斐波那契数列](#2.2.1 斐波那契数列)
[2.2.2 my_strlen](#2.2.2 my_strlen)
[2.2.3 字符串逆序](#2.2.3 字符串逆序)
[2.2.4 顺序打印整型数](#2.2.4 顺序打印整型数)
[三. 几个常用函数](#三. 几个常用函数)
[3.1 atoi](#3.1 atoi)
[3.2 sprintf](#3.2 sprintf)
一. 函数的参数传递
1.1 变量传参
注意函数传参时:1、保证传递参数个数一样
2、保证传递的类型匹配
示例代码:
cpp
int Add(int x,int y)
{
return x + y;
}
int main()
{
int a = 10, b = 30;
int ret = Add(a,b);
return 0;
}
函数传参的具体过程

**注意:**函数传参采用传值时,形参只是实参的一份临时拷贝,改变形参并不能改变实参。
传值调用 : 实参把参数数据的内容通过赋值运算符给形参的形式。 形参是实参的一个副本(复制
品)。数据内容是相同的,实参的内存空间,和形参的内存,是独立。 没有办法通过修改形参来达
到修改实参的目的。值传递只能读取实参的值, 不能就行修改。
传址调用 :实参传递变量的内存地址值。 即可以读实参的数据的值 ,也可以修改。(数组的传参实际上就是传地址)
eg:下面的代码并不能实现两数交换
cpp
void swap(int a,int b)
{
int c = a;
a = b;
b = c;
printf("swap:a = %d,b = %d\n",a,b);
}
int main()
{
int a = 10, b = 20;
printf("before:a = %d,b = %d\n",a,b);
swap(a,b);
printf("main:a = %d,b = %d\n",a,b);
return 0;
}

1.2 数组传参
cpp
void arr_fill(int a[],int size)
{
//如果传参是数组类型,在被调内部,会被降级为指针(8字节)
int i = 0;
for(i = 0; i < size; i++)
{
a[i] = rand() % 20;//不是传值调用,所以可以修改
}
// printf("a size is %lu\n",sizeof(a));
}
void arr_print(int a[],int size)
{
int i = 0;
for(i = 0; i < size; i++)
{
printf("%3d ",a[i]);
if((i + 1) % 5 == 0)
puts("");
}
}
int main()
{
srand(time(NULL));
int arr[25];
int size = sizeof(arr) / sizeof(arr[0]);
arr_fill(arr,size);
arr_print(arr,size);
return 0;
}
1、数组传参时在被调函数内部会被降级为指针,在64位系统中大小是8字节,32位系统中大小是4字节。
2、int arr[10] 这个数组arr的类型是:int [10];
3、数组传参时是传址,故在函数内部可以对数组进行改变
4、在被调函数内部不可计算数组的大小,sizeof(arr) = 8/4。应该在主函数计算之后传参给被调函数
1.3 整型数组的几个练习
填充与打印数组:
cpp
void arr_fill(int a[],int size)
{
//如果传参是数组类型,在被调内部,会被降级为指针(8字节)
int i = 0;
for(i = 0; i < size; i++)
{
a[i] = rand() % 20;//不是传值调用,所以可以修改
}
// printf("a size is %lu\n",sizeof(a));
}
void arr_print(int a[],int size)
{
int i = 0;
for(i = 0; i < size; i++)
{
printf("%3d ",a[i]);
// if((i + 1) % 5 == 0)
// puts("");
}
puts("");
}
反转数组:
cpp
void reverse_arrry(int a[],int size)
{
int i = 0;
for(i = 0;i < size / 2; i++)
{
int temp = a[i];
a[i] = a[size - 1 - i];
a[size - 1 - i] = temp;
}
}
对数组中的数据进行排序:
cpp
//插入排序
void insert_sort(int a[],int size)
{
int i, j;
for(i = 0; i < size - 1; i++)
{
j = i + 1;
int temp = a[j];
while(j > 0 && a[j - 1] > temp)
{
a[j] = a[j - 1];
j--;
}
a[j] = temp;
}
}
//冒泡排序
int bubble_sort(int a[],int size)
{
int i, j;
for(i = 1; i < size; i++)
{
int flag = 0;
for(j = 0; j < size - i ;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
flag = 1;
}
}
if(flag == 0)
break;
}
return 0;
}
//选择排序
int chose_sort(int a[],int size)
{
int i, j;
for(i = 0; i < size - 1;i++)
{
for(j = i + 1;j < size;j++)
{
if(a[j] < a[i])
{
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
return 0;
}
1.4 字符数组的几个练习
实现strlen
cpp
nt my_strlen(char a[])
{
int len = 0;
while(a[len])
{
len++;
}
return len;
}
实现strcpy
注意strcpy与memcpy的区别:


strcpy会将**'\0'**也一同拷贝到dst,而memcpy则根据指定的count去拷贝数据。
cpp
int my_strcpy(char dst[],char src[])
{
int i = 0, j = 0;
while(src[i])
{
dst[j++] = src[i++];
}
dst[i] = '\0';
return 0;
}
实现strcat
cpp
int my_strcat(char dst[],char src[])
{
int i = 0, j = 0;
while(dst[i])
{
i++;
}
while(src[j])
{
dst[i++] = src[j++];
}
dst[i] = '\0';
return 0;
}
实现strcmp
cpp
int my_strcmp(char str1[],char str2[])
{
int i = 0, j = 0;
while(str1[i] == str2[j] && str1[i] != '\0')
{
i++;
j++;
}
return str1[i] - str2[j];
}
二. 函数递归
在函数内部,自己调用自己的函数调用,被称为函数的递归。
属于循环的一种表现形式。但会使用栈空间 。
注意:需要设置合理的退出条件。递归的层次不要太深,会消耗大量的内存,可能导致程序崩溃。应用,回溯类,逆向思维的问题的。
注意:Linux栈区仅8M,死递归会出现段错误:

2.1 递归求阶乘
cpp
int fun(int n)
{
if(1 == n || 0 == n)
return 1;
else
return fun(n-1) * n;
}
函数递归展开图:

2.2 递归的其他几个练习
2.2.1 斐波那契数列
cpp
int Fib(int n)
{
if(n == 1 || n == 2)
return 1;
return Fib(n - 1) + Fib(n - 2);
}
2.2.2 my_strlen
cpp
int my_strlen(char *a)
{
if(*a == '\0')
return 0;
return 1 + my_strlen(a+1);
}
2.2.3 字符串逆序
cpp
void reverse(char *a,int left,int right)
{
if(left < right)
{
char temp = a[left];
a[left] = a[right];
a[right] = temp;
reverse(a,left+1,right-1);
}
}
2.2.4 顺序打印整型数
cpp
void print(int a)
{
if(a < 10)
printf("%d ",a);
else
{
print(a / 10);
printf("%d ",a % 10);
}
}
三. 几个常用函数
3.1 atoi

描述:C 库函数 把参数 str 所指向的字符串转换为一个整数(类型为 int 型)
返回值:该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。


3.2 sprintf
描述:`sprintf` 函数会将一系列字符和值格式化并存储在缓冲区中。每个参数(如果有)都会根据 `format` 中对应的格式说明进行转换并输出。格式由普通字符组成,其形式和功能与 `printf` 的格式参数相同。在写入最后一个字符后会添加一个空字符。如果在重叠的字符串之间进行复制,其行为是未定义的。
返回值:如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

