C语言入门part6–函数
关键字:库函数,自定义函数,函数的嵌套调用及链式访问,递归,strlen 和sizeof的区别,* p++和(*p)++的区别
库函数
-
strlen
-
在头文件<string.h>里
-
strlen(ch1)
与int len = sizeof(ch1) / sizeof(ch1[0]);
作用相同,都是求字符串数组的大小 -
注意strlen 和sizeof的区别
sizeof
指文件或者数据占的内存(字节),包括‘\0’strlen
指字符的长度 不包括‘\0’
-
strcpy 字符串复制 strcat字符串拼接
char string[80];
char ch[]="Hello world ";
strcpy( string, ch ); // 或者这两行改为 strcpy( string, "Hello world from " );
strcat( string, "strcpy " );
strcat( string, "and " );
strcat( string, "strcat!" );
printf( "String = %s\n", string );
运行结果 String = Hello world from strcpy and strcat!
-
memset 将内存块设置为指定的字符
char dest[10]="abcdef"; memset(dest,'g',4)//dest数组中前四个变成g
-
scanf 接收数组时数组名前不用加&,只用数组名就行
-
strcmp 比较字符串
char string1[] = "abcde";
char string2[] = "abcde";
int result = strcmp(string1, string2);//strcmp(a,b)=0则说明字符串a和字符串b相等
自定义函数
自定义函数要注意:
-
参数:个数要匹配,参数的类型, 按值传递形参的改变不改变形参的值, 按址传递会改变实参的值(经典例子交换数值函数)
-
返回值:如果有返回值,则必须返回一个值,否则会有警告,返回值类型也需要匹配。如果没有返回值,不能return
-
函数名:C语言中建议函数名遵循驼峰式命名(即首字母大写)
// 判断素数
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Prime(int num)//是素数返回1,不是返回0
{
int i = 0;
for (i = 2; i <= num / 2; i++)
{
if (num%i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
int num = 0;
printf("请输入你要判断的数字:");
scanf("%d", &num);
int ret=Prime(num);
if(ret==1)
{
printf(“is prime\n”);
}
else
{
printf("is not prime\n");
}
return 0;
}
//每调用一次函数num加一
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void Plus(int *p)
{
(*p)++;//必须要加括号* p++和(*p)++的区别
}
int main()
{
int num = 1;
for (int i = 0; i < 5; i++)
{
Plus(&num);
}
printf("%d", num);
return 0;
}
* p++和(*p)++的区别
-
a=*p++
等价于 *(p++) 即a = *p; p = p + 1;
-
a=(*p)++
等价于 *p ;*p+1
函数的嵌套调用
- 函数和函数之间的结合
eg: 嵌套调用实现三遍hehe 的打印
#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()
{
three_line();
return 0;
}
函数的链式访问
- 链式访问即把一个函数的返回值当作另一个函数的参数
eg:
char arr[20] = "hello";
int ret = strlen(strcat(arr,"world"));//将world拼接在hello后面得helloworld再调用strlen求该字符串长度
printf("%d\n", ret);//打印10
函数的递归
-
函数自己调用自己本身,将大问题划分成小问题
-
递归需要满足两个条件:
1.循环调用自己本身
2.有一个趋近于终止的条件 -
技巧 横向思考问题 纵向执行代码
-
所有递归的执行,都是发生在栈上(栈的特性:先进后出)所以若提示堆栈溢出 一般都是递归没有给终止条件或者是终止条件不对
eg:
- 第五个人比第四个小两岁,第四个比第三个小2岁…第一个人10岁,求第五个人年龄?
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Age(int i)
{
if (i == 1)
{
return 10;
}
else
{
return 2 + Age(i - 1);
}
}
int main()
{
printf("%d",Age(5));
return 0;
}
- 1234打印1 2 3 4
#include<stdio.h>
void Show(int i)
{
if (i > 9)
{
Show(i / 10);
}
printf("%d ", i%10);
}
int main()
{
Show(1234);
return 0;
}
- 汉诺塔
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void Move(char pos1, char pos2)
{
printf("%c->%c\n", pos1, pos2);
}
void Hanota(int n, char pos1, char pos2, char pos3)
{
if (n == 1)
{
Move(pos1, pos3);
}
else
{
Hanota(n - 1, pos1, pos3, pos2);
Move(pos1, pos3);
Hanota(n - 1, pos2, pos1, pos3);
}
}
int main()
{
Hanota(4, 'A', 'B', 'C');
return 0;
}