C语言笔记(七)
2016-05-16 14:56
465 查看
1、什么是函数
scanf ————>实现输入功能
printf
————>实现输出功能
getchar
————>实现单个字符输入功能
putchar
————>实现单个字符输出功能
gets ————>实现字符串输入功能
puts ————>实现字符串输出功能
fgets ————>实现字符串输入功能
fputs ————>实现字符串输出功能
strlen
————>实现计算字符串长度功能
bzero ————>实现计算字符串清空功能
atoi ————>实现计算字符串转整型功能
strcat
————>实现计算字符串拼接功能
strcpy
————>实现计算字符串复制功能
strcmp
————>实现计算字符串比较功能
strchr
————>实现计算字符串中查找字符功能
strstr
————>实现计算字符串中查找子串功能
总结:一个函数对应一个功能,函数实际就是对功能代码的封装,函数名实际就是功能名
函数特点:函数功能尽量要单一
2、函数的封装
思考:对10个数和100个数进行排序
void sort(int arr[], int n)
{
//对10个数排序
for (j=0; j<10; j++){
for (i=0; i<9; i++){//冒泡
if (arr[i] > arr[i+1]){//相邻成员比较
tmp = arr[i];//交换
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
}
//对100个数排序
for (j=0; j<100; j++){
for (i=0; i<99; i++){//冒泡
if (brr[i] > brr[i+1]){//相邻成员比较
tmp = brr[i];//交换
brr[i] = brr[i+1];
brr[i+1] = tmp;
}
}
}
总结:
相同点:都是在实现同一个功能(排序功能),操作的数据的数据类型相同的(都是数组)
不同点:操作的数据的个数不同
函数的封装:首先找到实现函数功能的代码,用大括号{}括起来(函数体),对这段功能代码起一个名字(函数名),把函数体中需要操作的数据放到函数名后面的小括号(函数形参),在函数名前面加上一个数据类型(函数的类型或函数返回值的类型)
3、函数的优点
在一个程序中,我们只需要实现一个函数的功能代码,在程序的任何地方需要使用该功能时,只需要一条函数调用语句即可,无需再次实现函数功能。我编写的函数,可以编译生成动态库和静态库,对外提供接口,给其他程序员使用
总结:代码的复用
4、常见函数的种类
库函数:标准库提供的函数
自定义函数:程序员根据程序的需要自己编写的函数
5、使用函数需要具备的条件
库函数:包含函数声明头文件,需要在编译的最后一个阶段链接函数库
自定义函数:函数的定义,声明,调用
6、一个完整的自定义函数需要包含哪些内容
#include <stdio.h>
int add(int a, int b);//函数的声明
int main(int argc, const char *argv[])
{
int c = 3;
int d = 5;
int e = add(c, d);//函数调用
printf("e = %d\n", e);
return 0;
}
int add(int a, int b)//函数的定义
{
return (a+b);
}
`
总结:函数定义,声明,调用
7、函数的定义
函数的定义:实现函数功能
格式:
数据类型 函数名(形参列表)
{
函数体;
}
函数名:本质功能名,函数名是地址常量,等于函数的入口地址
形参列表:由多个数据类型加变量名构成,中间用逗号隔开,函数调用开始前,形参不占用任何存储空间(函数没有形参写成void)
数据类型:函数类型或函数返回值的类型,和return返回的数据的数据类型相同(void)
{}:{函数的开始,}函数的结束,{}中间是函数体,函数的实现
8、函数的调用
函数的调用:函数的使用
格式:函数名(实参列表)
函数名:函数定义时的名字
实参列表:实参可以是常量、变量、还可以是表达式,但是一定要有一个具体的值,当发生函数调用时,首先计算实参的值,将实参的值传递给形参,在函数体中操作形参的值,最终得到想要的结果
函数调用的常见形式:
1:函数调用语句:当函数没有返回值的时候可以直接调用该参数
例子:sort(int a[],int n);
2:函数表达式:当函数有返回值的时候,可以将函数的返回值参与表达式的计算
例子:int a=max(a,b)+c;
3:函数的实参:当函数有返回值的时候,可以将函数的返回值作为另一个函数的实参
例子:max(max(a,b),c);
9、函数的声明
函数的声明:将函数的相关信息告诉编译器,在发生函数调用时,对函数信息进行检查(形参的个数,形参的类型,形参的顺序....)
格式:
数据类型 函数名(形参列表);
函数定义的第一句话末尾加上分号
函数声明的位置:
1:文件开始处,函数调用前
2:main函数里,函数调用前
3:如果函数定义在文件开始,函数调用前,那么函数声明可以省略
#include <stdio.h>
int max(int a, int b);//定义
int main(int argc, const char *argv[])
{
int a = 3;
int b = 5;
printf("max(a, b) = %d\n", max(a, b));//函数调用
return 0;
}
int max(int a, int b)//定义
{
return (a>b?a:b);
}
10、函数调用的整个过程
1:函数调用开始前,系统不会为函数的形参开辟任何存储空间
2:当发生函数调用时,首先计算实参的值,将计算的结果传递给形参(函数传参时值的传递)
3:当形参接受到实参的值后,就可以在函数体中操作形参,得到结果
4:函数调用结束时,通过return将返回值给主调函数
5:函数调用结束后,系统为形参在栈上开辟的任何存储空间都会被释放
函数调用:压栈
函数调用结束:出栈
11、函数和其他数据类型的结合
1:函数的参数是基本数据类型
练习:
1:判断一个数n能否同时被3和5整除
#include <stdio.h>
void judge(int n);//函数的声明
int main(int argc, const char *argv[])
{
int n = 0;
scanf("%d", &n);
judge(n);//函数调用
return 0;
}
void judge(int n)//函数的定义
{
if ((n%3==0) && (n%5==0)){
printf("YES\n");
} else {
printf("NO\n");
}
}
2:写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用者两个函数,并输出结果。两个整数由键盘输入。
n1 n2
12 18
12……1
for (i=12; i>=1; i- -){
if ((n1%i==0) && (n2%i==0)){
break;
}
}
最小公倍数:能把n1和n2同时整除的最小的数
n1 n2
12 18
for(i = 18; i<=n1*n2; i++)
if (i%n1==0 && i%n2==0){
break;
}
#include <stdio.h>
int common_divisor(int n1, int n2);//函数声明
int common_multiple(int n1, int n2);//函数声明
int main(int argc, const char *argv[])
{
int n1 = 0;
int n2 = 0;
scanf("%d", &n1);
scanf("%d", &n2);
printf("common_divisor(n1, n2) = %d\n", common_divisor(n1, n2));//函数调用
printf("common_multiple(n1, n2) = %d\n", common_multiple(n1, n2));//函数调用
return 0;
}
int common_divisor(int n1, int n2)//函数定义
{
int i = 0;
for (i=(n1<n2?n1:n2); i>=1; i--){
if ((n1%i==0) && (n2%i==0)){
break;
}
}
return i;
}
int common_multiple(int n1, int n2)//函数定义
{
int i = 0;
for (i=(n1>n2?n1:n2); i<=(n1*n2); i++){
if ((i%n1==0) && (i%n2==0)){
break;
}
}
return i;
}
2:函数参数可以是数值型数组名
函数的行参:int arr[], int n
函数的实参:arr , 数组成员个数
练习:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int score[], int n);//函数的声明
void output(int score[], int n);
int average(int score[], int n);
int main(int argc, const char *argv[])
{
int score[NUM] = {};
input(score, NUM);//函数调用
output(score, NUM);
printf("average = %d\n", average(score, NUM));
return 0;
}
void input(int score[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
score[i] = rand()%100;
}
}
void output(int score[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", score[i]);
}
printf("\n");
}
int average(int score[], int n)
{
int i = 0;
int sum = 0;
for (i=0; i<n; i++){//求平均年龄
sum = sum + score[i];
}
return (sum/n);
}
1:有一个一维数组score,保存10个学生的年龄,求平均年龄
2:用冒泡法对数组进行排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int arr[], int n);//函数的声明
void output(int arr[], int n);
void maopao(int arr[], int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int arr[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
arr[i] = rand()%100;
}
}
void output(int arr[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", arr[i]);
}
printf("\n");
}
void maopao(int arr[], int n)
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){
for (i=0; i<n-1; i++){
if (arr[i] > arr[i+1]){
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
}
3:将数组a中的成员按相反顺序存放(逆序)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int arr[], int n);//函数的声明
void output(int arr[], int n);
void turn(int arr[], int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
turn(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int arr[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
arr[i] = rand()%100;
}
}
void output(int arr[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", arr[i]);
}
printf("\n");
}
void turn(int arr[], int n)
{
int i = 0;
int tmp = 0;
for (i=0; i<n/2; i++){
tmp = arr[i];//交换
arr[i] = arr[n-1-i];
arr[n-1-i] = tmp;
}
}
3:函数参数可以是字符型数组名
函数的行参:char buf[]
函数实参:buf
练习:
1:
输入一个字符串,统计其中数字字符的个数
#include <stdio.h>
#define SIZE 100
int total(char buf[]);//函数声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("total(buf) = %d\n", total(buf));//函数调用
return 0;
}
int total(char buf[])//函数定义
{
int i = 0;
int t = 0;
for (i=0; buf[i]; i++){
if ((buf[i]>='0') && (buf[i]<='9')){
t++;
}
}
return t;
}
3:实现字符串处理函数strcat
char *my_strcat(char buf1[], char buf2[]);
#include <stdio.h>
#define SIZE 100
char *my_strcat(char buf1[], char buf2[]);//声明
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
gets(buf1);
gets(buf2);
printf("%s\n", my_strcat(buf1, buf2));//函数调用
return 0;
}
char *my_strcat(char buf1[], char buf2[])//实现
{
int i = 0;
int j = 0;
for (i=0; buf1[i]; i++);
for (j=0; buf2[j]; j++){
buf1[i+j] = buf2[j];
}
return buf1;
}
交换两个数的值
#include <stdio.h>
void swap(int *pa, int *pb);//函数声明
int main(int argc, const char *argv[])
{
int a = 3;
int b = 5;
int tmp = 0;
printf("a = %d\n", a);
printf("b = %d\n", b);
swap(&a, &b);//函数调用
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
void swap(int *pa, int *pb)//函数定义
{
int *ptmp = NULL;
ptmp = pa;
pa = pb;
pb = ptmp;
printf("*pa = %d\n", *pa);
printf("*pb = %d\n", *pb);
}
4:函数参数是指向数值数组首元素的指针
函数实参:arr, n
函数行参:int arr[], int n
函数行参:int *pArr, int n
练习:
1:有一个一维数组score,保存10个学生的年龄,求平均年龄
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
int average(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
printf("average = %d\n", average(arr, NUM));
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
int average(int *pArr, int n)//函数的定义
{
// int i = 0;
int sum = 0;
int *pArrCp = pArr;
// for (i=0; i<n; i++){
// sum = sum + *(pArr+i);
// }
for (; pArrCp<(pArr+n); sum = sum + *pArrCp++);
return sum/n;
}
2:用冒泡法对数组进行排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void maopao(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
void maopao(int *pArr, int n)//函数的定义
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (*(pArr+i) > *(pArr+i+1)){//相邻成员比较
tmp = *(pArr+i);//交换
*(pArr+i) = *(pArr+i+1);
*(pArr+i+1) = tmp;
}
}
}
}
3:将数组a中的成员按相反顺序存放(逆序)
4:在有序的数组中插入整数n
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void maopao(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
void insert(int *pArr, int nArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM+1] = {};
int n = 0;
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
scanf("%d", &n);
insert(arr, NUM, n);
output(arr, NUM+1);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
void maopao(int *pArr, int n)//函数的定义
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (*(pArr+i) > *(pArr+i+1)){//相邻成员比较
tmp = *(pArr+i);//交换
*(pArr+i) = *(pArr+i+1);
*(pArr+i+1) = tmp;
}
}
}
}
void insert(int *pArr, int nArr, int n)
{
int i = 0;
int j = 0;
for (i=0, *(pArr+nArr)=n; i<nArr; i++){//遍历数组
if (*(pArr+i) > n){//找到插入的位置
for (j=nArr-1; j>=i; j--){//循环后移
*(pArr+j+1) = *(pArr+j);
}
*(pArr+i) = n;//插入
break;
}
}
}
5:在有序的数组中删除整数n
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
int delete(int *pArr, int nArr, int n);//函数的定义
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
int n = 0;
int t = 0;
input(arr, NUM);//函数调用
output(arr, NUM);
scanf("%d", &n);
t = delete(arr, NUM, n);
output(arr, NUM-t);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
int delete(int *pArr, int nArr, int n)//函数的定义
{
int i = 0;
int j = 0;
int t = 0;
for (i=0; i<(nArr-t); i++){//遍历数组
if (*(pArr+i) == n){//找到删除的数
for (j=i; j<(nArr-1-t); j++){//循环前移
*(pArr+j) = *(pArr+j+1);
}
t++;//计数
i--;//相邻
}
}
return t;
}
1:遍历数组找到需要删除的数
2:前移
5:函数参数是指向字符数组首元素的指针
练习
8:给定一个英文句子,单词之间用1个空格分开,求其中所有单词的数量
#include <stdio.h>
#include <string.h>
#define SIZE 100
int findWordNum(char *pBuf);
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("findWordNum(buf) = %d\n", findWordNum(buf));
return 0;
}
int findWordNum(char *pBuf)
{
int i = 0;
//sdfkh sdkfjhsdf sdf sdf
for (; (pBuf=strchr(pBuf, ' ')); pBuf++, i++);
return i+1;
}
9:删除字符串中的数字字符
#include <stdio.h>
#include <string.h>
#define SIZE 100
char *deleteNumCh(char *pBuf);//声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("deleteNumCh(buf) = %s\n",deleteNumCh(buf));//函数调用
return 0;
}
char *deleteNumCh(char *pBuf)//定义
{
int i = 0;
int j = 0;
for (i=0; *(pBuf+i); i++){
if ((*(pBuf+i)>='0') && (*(pBuf+i)<='9')){
for (j=i; *(pBuf+j); j++){
*(pBuf+j) = *(pBuf+j+1);
}
i--;
}
}
return pBuf;
}
10:将字符串中连续出现的空格(两个以上)合并成一个
#include <stdio.h>
#include <string.h>
#define SIZE 100
char *deleteSpace(char *pBuf);//定义
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("deleteSpace(buf) = %s\n",deleteSpace(buf));//函数调用
return 0;
}
char *deleteSpace(char *pBuf)//定义
{
char *pBufCp = pBuf;
char *pCp = NULL;
//sdk dfd fgf fgf
for (; (pBuf=strstr(pBuf, " ")); pBuf++){//遍历字符串
for (pCp=pBuf; *pCp; pCp++){//循环前移
*pCp = *(pCp+1);
}
pBuf--;
}
return pBufCp;
}
11:找出字符串中首次只出现一次的字符
#include <stdio.h>
#include <string.h>
#define SIZE 100
char findFirstOneCh(char *pBuf);//声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("findFirstOneCh(buf) = %c\n", findFirstOneCh(buf));//函数调用
return 0;
}
char findFirstOneCh(char *pBuf)//定义
{
int flag = 0;
int i = 0;
int j = 0;
for (i=0; *(pBuf+i); i++){//遍历字符串
for (j=0, flag=0; *(pBuf+j); j++){//遍历字符串
if (*(pBuf+i) == *(pBuf+j)){//找到出现的字符
flag++;//计数
}
}
if (flag == 1){//找到了
return *(pBuf+i);
}
}
return 0;
}
6:函数参数是指针数组
char *pArr[5];
函数的行参:char *pArr[], int n
函数的实参:pArr, 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM 5
#define SIZE 100
void input(char *pArr[], int n);
void output(char *pArr[], int n);
char *maxBuf(char *pArr[], int n);
int main(int argc, const char *argv[])
{
char *pArr[NUM] = {malloc(SIZE), malloc(SIZE),malloc(SIZE),malloc(SIZE),malloc(SIZE),};
input(pArr, NUM);
output(pArr, NUM);
printf("max = %s\n", maxBuf(pArr, NUM));
for (int i=0; i<NUM; i++){
free(pArr[i]);
}
return 0;
}
void input(char *pArr[], int n)
{
int i = 0;
for (i=0; i<n; i++){
gets(pArr[i]);
}
}
void output(char *pArr[], int n)
{
int i = 0;
for (i=0; i<n; i++){
puts(pArr[i]);
}
}
char *maxBuf(char *pArr[], int n)
{
char *pMax = NULL;
int i = 0;
for (pMax=pArr[0], i=0; i<n; i++){
if (strcmp(pMax, pArr[i]) < 0){
pMax = pArr[i];
}
}
return pMax;
}
5个字符串找出最大的字符串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM 5
#define SIZE 100
void input(char **pp, int n);
void output(char **pp, int n);
void maopao(char **pp, int n);
int main(int argc, const char *argv[])
{
char *pArr[NUM] = {malloc(SIZE), malloc(SIZE),malloc(SIZE),malloc(SIZE),malloc(SIZE),};
input(pArr, NUM);
maopao(pArr, NUM);
output(pArr, NUM);
return 0;
}
void input(char **pp, int n)
{
int i = 0;
for (i=0; i<n; i++){
gets(*(pp+i));
}
}
void output(char **pp, int n)
{
int i = 0;
for (i=0; i<n; i++){
puts(*(pp+i));
}
}
void maopao(char **pp, int n)
{
int i = 0;
char *pTmp = NULL;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (strcmp(*(pp+i), *(pp+i+1)) > 0){
pTmp = *(pp+i);
*(pp+i) = *(pp+i+1);
*(pp+i+1) = pTmp;
}
}
}
}
7:函数参数是二级指针
函数的行参:char *pArr[], int n
函数的行参:char **pp, int n
函数的实参:pArr, 5
实现五个字符串的排序
8:函数参数是结构体变量
9:函数参数是结构体数组
12、函数指针和指针函数
函数指针:指针,保存函数的入口地址
函数指针的定义:
int add(int a, int b);
int (*p)(int a, int b) = add;
int *p(int a, int b)
练习:
char *my_stcat(char *p1, char *p2);
char *(*p)(char *p1, char *p2) = my_stcat;
int **fun(int *pa, char **pb, int *p[]);
int **(*p)(int *pa, char **pb, int *p[]) = fun;
#include <stdio.h>
int max(int a, int b)
{
return a>b?a:b;
}
int min(int a, int b)
{
return a<b?a:b;
}
int main(int argc, const char *argv[])
{
//max(3, 5);
int (*p)(int a, int b) = NULL;
p = max;
printf("max(3, 5) = %d\n", max(3, 5));
printf("p(3, 5) = %d\n", p(3, 5));
p = min;
printf("p(3, 5) = %d\n", p(3, 5));
return 0;
}
指针函数:函数,函数的返回值是指针
13、main函数的参数
#include <stdio.h>
int main(int argc, const char *argv[])
{
for (int i=0; i<argc; i++){
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
scanf ————>实现输入功能
printf
————>实现输出功能
getchar
————>实现单个字符输入功能
putchar
————>实现单个字符输出功能
gets ————>实现字符串输入功能
puts ————>实现字符串输出功能
fgets ————>实现字符串输入功能
fputs ————>实现字符串输出功能
strlen
————>实现计算字符串长度功能
bzero ————>实现计算字符串清空功能
atoi ————>实现计算字符串转整型功能
strcat
————>实现计算字符串拼接功能
strcpy
————>实现计算字符串复制功能
strcmp
————>实现计算字符串比较功能
strchr
————>实现计算字符串中查找字符功能
strstr
————>实现计算字符串中查找子串功能
总结:一个函数对应一个功能,函数实际就是对功能代码的封装,函数名实际就是功能名
函数特点:函数功能尽量要单一
2、函数的封装
思考:对10个数和100个数进行排序
void sort(int arr[], int n)
{
//对10个数排序
for (j=0; j<10; j++){
for (i=0; i<9; i++){//冒泡
if (arr[i] > arr[i+1]){//相邻成员比较
tmp = arr[i];//交换
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
}
//对100个数排序
for (j=0; j<100; j++){
for (i=0; i<99; i++){//冒泡
if (brr[i] > brr[i+1]){//相邻成员比较
tmp = brr[i];//交换
brr[i] = brr[i+1];
brr[i+1] = tmp;
}
}
}
总结:
相同点:都是在实现同一个功能(排序功能),操作的数据的数据类型相同的(都是数组)
不同点:操作的数据的个数不同
函数的封装:首先找到实现函数功能的代码,用大括号{}括起来(函数体),对这段功能代码起一个名字(函数名),把函数体中需要操作的数据放到函数名后面的小括号(函数形参),在函数名前面加上一个数据类型(函数的类型或函数返回值的类型)
3、函数的优点
在一个程序中,我们只需要实现一个函数的功能代码,在程序的任何地方需要使用该功能时,只需要一条函数调用语句即可,无需再次实现函数功能。我编写的函数,可以编译生成动态库和静态库,对外提供接口,给其他程序员使用
总结:代码的复用
4、常见函数的种类
库函数:标准库提供的函数
自定义函数:程序员根据程序的需要自己编写的函数
5、使用函数需要具备的条件
库函数:包含函数声明头文件,需要在编译的最后一个阶段链接函数库
自定义函数:函数的定义,声明,调用
6、一个完整的自定义函数需要包含哪些内容
#include <stdio.h>
int add(int a, int b);//函数的声明
int main(int argc, const char *argv[])
{
int c = 3;
int d = 5;
int e = add(c, d);//函数调用
printf("e = %d\n", e);
return 0;
}
int add(int a, int b)//函数的定义
{
return (a+b);
}
`
总结:函数定义,声明,调用
7、函数的定义
函数的定义:实现函数功能
格式:
数据类型 函数名(形参列表)
{
函数体;
}
函数名:本质功能名,函数名是地址常量,等于函数的入口地址
形参列表:由多个数据类型加变量名构成,中间用逗号隔开,函数调用开始前,形参不占用任何存储空间(函数没有形参写成void)
数据类型:函数类型或函数返回值的类型,和return返回的数据的数据类型相同(void)
{}:{函数的开始,}函数的结束,{}中间是函数体,函数的实现
8、函数的调用
函数的调用:函数的使用
格式:函数名(实参列表)
函数名:函数定义时的名字
实参列表:实参可以是常量、变量、还可以是表达式,但是一定要有一个具体的值,当发生函数调用时,首先计算实参的值,将实参的值传递给形参,在函数体中操作形参的值,最终得到想要的结果
函数调用的常见形式:
1:函数调用语句:当函数没有返回值的时候可以直接调用该参数
例子:sort(int a[],int n);
2:函数表达式:当函数有返回值的时候,可以将函数的返回值参与表达式的计算
例子:int a=max(a,b)+c;
3:函数的实参:当函数有返回值的时候,可以将函数的返回值作为另一个函数的实参
例子:max(max(a,b),c);
9、函数的声明
函数的声明:将函数的相关信息告诉编译器,在发生函数调用时,对函数信息进行检查(形参的个数,形参的类型,形参的顺序....)
格式:
数据类型 函数名(形参列表);
函数定义的第一句话末尾加上分号
函数声明的位置:
1:文件开始处,函数调用前
2:main函数里,函数调用前
3:如果函数定义在文件开始,函数调用前,那么函数声明可以省略
#include <stdio.h>
int max(int a, int b);//定义
int main(int argc, const char *argv[])
{
int a = 3;
int b = 5;
printf("max(a, b) = %d\n", max(a, b));//函数调用
return 0;
}
int max(int a, int b)//定义
{
return (a>b?a:b);
}
10、函数调用的整个过程
1:函数调用开始前,系统不会为函数的形参开辟任何存储空间
2:当发生函数调用时,首先计算实参的值,将计算的结果传递给形参(函数传参时值的传递)
3:当形参接受到实参的值后,就可以在函数体中操作形参,得到结果
4:函数调用结束时,通过return将返回值给主调函数
5:函数调用结束后,系统为形参在栈上开辟的任何存储空间都会被释放
函数调用:压栈
函数调用结束:出栈
11、函数和其他数据类型的结合
1:函数的参数是基本数据类型
练习:
1:判断一个数n能否同时被3和5整除
#include <stdio.h>
void judge(int n);//函数的声明
int main(int argc, const char *argv[])
{
int n = 0;
scanf("%d", &n);
judge(n);//函数调用
return 0;
}
void judge(int n)//函数的定义
{
if ((n%3==0) && (n%5==0)){
printf("YES\n");
} else {
printf("NO\n");
}
}
2:写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用者两个函数,并输出结果。两个整数由键盘输入。
n1 n2
12 18
12……1
for (i=12; i>=1; i- -){
if ((n1%i==0) && (n2%i==0)){
break;
}
}
最小公倍数:能把n1和n2同时整除的最小的数
n1 n2
12 18
for(i = 18; i<=n1*n2; i++)
if (i%n1==0 && i%n2==0){
break;
}
#include <stdio.h>
int common_divisor(int n1, int n2);//函数声明
int common_multiple(int n1, int n2);//函数声明
int main(int argc, const char *argv[])
{
int n1 = 0;
int n2 = 0;
scanf("%d", &n1);
scanf("%d", &n2);
printf("common_divisor(n1, n2) = %d\n", common_divisor(n1, n2));//函数调用
printf("common_multiple(n1, n2) = %d\n", common_multiple(n1, n2));//函数调用
return 0;
}
int common_divisor(int n1, int n2)//函数定义
{
int i = 0;
for (i=(n1<n2?n1:n2); i>=1; i--){
if ((n1%i==0) && (n2%i==0)){
break;
}
}
return i;
}
int common_multiple(int n1, int n2)//函数定义
{
int i = 0;
for (i=(n1>n2?n1:n2); i<=(n1*n2); i++){
if ((i%n1==0) && (i%n2==0)){
break;
}
}
return i;
}
2:函数参数可以是数值型数组名
函数的行参:int arr[], int n
函数的实参:arr , 数组成员个数
练习:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int score[], int n);//函数的声明
void output(int score[], int n);
int average(int score[], int n);
int main(int argc, const char *argv[])
{
int score[NUM] = {};
input(score, NUM);//函数调用
output(score, NUM);
printf("average = %d\n", average(score, NUM));
return 0;
}
void input(int score[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
score[i] = rand()%100;
}
}
void output(int score[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", score[i]);
}
printf("\n");
}
int average(int score[], int n)
{
int i = 0;
int sum = 0;
for (i=0; i<n; i++){//求平均年龄
sum = sum + score[i];
}
return (sum/n);
}
1:有一个一维数组score,保存10个学生的年龄,求平均年龄
2:用冒泡法对数组进行排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int arr[], int n);//函数的声明
void output(int arr[], int n);
void maopao(int arr[], int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int arr[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
arr[i] = rand()%100;
}
}
void output(int arr[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", arr[i]);
}
printf("\n");
}
void maopao(int arr[], int n)
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){
for (i=0; i<n-1; i++){
if (arr[i] > arr[i+1]){
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
}
}
}
}
3:将数组a中的成员按相反顺序存放(逆序)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void input(int arr[], int n);//函数的声明
void output(int arr[], int n);
void turn(int arr[], int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
turn(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int arr[], int n)//函数的定义
{
int i = 0;
srand(time(NULL));
for (i=0; i<n; i++){//输入
arr[i] = rand()%100;
}
}
void output(int arr[], int n)
{
int i = 0;
for (i=0; i<n; i++){//输出
printf("%d ", arr[i]);
}
printf("\n");
}
void turn(int arr[], int n)
{
int i = 0;
int tmp = 0;
for (i=0; i<n/2; i++){
tmp = arr[i];//交换
arr[i] = arr[n-1-i];
arr[n-1-i] = tmp;
}
}
3:函数参数可以是字符型数组名
函数的行参:char buf[]
函数实参:buf
练习:
1:
输入一个字符串,统计其中数字字符的个数
#include <stdio.h>
#define SIZE 100
int total(char buf[]);//函数声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("total(buf) = %d\n", total(buf));//函数调用
return 0;
}
int total(char buf[])//函数定义
{
int i = 0;
int t = 0;
for (i=0; buf[i]; i++){
if ((buf[i]>='0') && (buf[i]<='9')){
t++;
}
}
return t;
}
3:实现字符串处理函数strcat
char *my_strcat(char buf1[], char buf2[]);
#include <stdio.h>
#define SIZE 100
char *my_strcat(char buf1[], char buf2[]);//声明
int main(int argc, const char *argv[])
{
char buf1[SIZE] = "";
char buf2[SIZE] = "";
gets(buf1);
gets(buf2);
printf("%s\n", my_strcat(buf1, buf2));//函数调用
return 0;
}
char *my_strcat(char buf1[], char buf2[])//实现
{
int i = 0;
int j = 0;
for (i=0; buf1[i]; i++);
for (j=0; buf2[j]; j++){
buf1[i+j] = buf2[j];
}
return buf1;
}
交换两个数的值
#include <stdio.h>
void swap(int *pa, int *pb);//函数声明
int main(int argc, const char *argv[])
{
int a = 3;
int b = 5;
int tmp = 0;
printf("a = %d\n", a);
printf("b = %d\n", b);
swap(&a, &b);//函数调用
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
void swap(int *pa, int *pb)//函数定义
{
int *ptmp = NULL;
ptmp = pa;
pa = pb;
pb = ptmp;
printf("*pa = %d\n", *pa);
printf("*pb = %d\n", *pb);
}
4:函数参数是指向数值数组首元素的指针
函数实参:arr, n
函数行参:int arr[], int n
函数行参:int *pArr, int n
练习:
1:有一个一维数组score,保存10个学生的年龄,求平均年龄
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
int average(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
printf("average = %d\n", average(arr, NUM));
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
int average(int *pArr, int n)//函数的定义
{
// int i = 0;
int sum = 0;
int *pArrCp = pArr;
// for (i=0; i<n; i++){
// sum = sum + *(pArr+i);
// }
for (; pArrCp<(pArr+n); sum = sum + *pArrCp++);
return sum/n;
}
2:用冒泡法对数组进行排序
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void maopao(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
void maopao(int *pArr, int n)//函数的定义
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (*(pArr+i) > *(pArr+i+1)){//相邻成员比较
tmp = *(pArr+i);//交换
*(pArr+i) = *(pArr+i+1);
*(pArr+i+1) = tmp;
}
}
}
}
3:将数组a中的成员按相反顺序存放(逆序)
4:在有序的数组中插入整数n
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
void maopao(int *pArr, int n);//函数的声明
void input(int *pArr, int n);
void output(int *pArr, int n);
void insert(int *pArr, int nArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM+1] = {};
int n = 0;
input(arr, NUM);//函数调用
output(arr, NUM);
maopao(arr, NUM);
output(arr, NUM);
scanf("%d", &n);
insert(arr, NUM, n);
output(arr, NUM+1);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
void maopao(int *pArr, int n)//函数的定义
{
int i = 0;
int tmp = 0;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (*(pArr+i) > *(pArr+i+1)){//相邻成员比较
tmp = *(pArr+i);//交换
*(pArr+i) = *(pArr+i+1);
*(pArr+i+1) = tmp;
}
}
}
}
void insert(int *pArr, int nArr, int n)
{
int i = 0;
int j = 0;
for (i=0, *(pArr+nArr)=n; i<nArr; i++){//遍历数组
if (*(pArr+i) > n){//找到插入的位置
for (j=nArr-1; j>=i; j--){//循环后移
*(pArr+j+1) = *(pArr+j);
}
*(pArr+i) = n;//插入
break;
}
}
}
5:在有序的数组中删除整数n
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM 10
int delete(int *pArr, int nArr, int n);//函数的定义
void input(int *pArr, int n);
void output(int *pArr, int n);
int main(int argc, const char *argv[])
{
int arr[NUM] = {};
int n = 0;
int t = 0;
input(arr, NUM);//函数调用
output(arr, NUM);
scanf("%d", &n);
t = delete(arr, NUM, n);
output(arr, NUM-t);
return 0;
}
void input(int *pArr, int n)
{
int *pArrCp = pArr;
srand(time(NULL));
for (; pArrCp<(pArr+n); pArrCp++){
*pArrCp = rand()%100;
}
}
void output(int *pArr, int n)
{
int *pArrCp = pArr;
for (; pArrCp<(pArr+n); pArrCp++){
printf("%d ", *pArrCp);
}
printf("\n");
}
int delete(int *pArr, int nArr, int n)//函数的定义
{
int i = 0;
int j = 0;
int t = 0;
for (i=0; i<(nArr-t); i++){//遍历数组
if (*(pArr+i) == n){//找到删除的数
for (j=i; j<(nArr-1-t); j++){//循环前移
*(pArr+j) = *(pArr+j+1);
}
t++;//计数
i--;//相邻
}
}
return t;
}
1:遍历数组找到需要删除的数
2:前移
5:函数参数是指向字符数组首元素的指针
练习
8:给定一个英文句子,单词之间用1个空格分开,求其中所有单词的数量
#include <stdio.h>
#include <string.h>
#define SIZE 100
int findWordNum(char *pBuf);
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("findWordNum(buf) = %d\n", findWordNum(buf));
return 0;
}
int findWordNum(char *pBuf)
{
int i = 0;
//sdfkh sdkfjhsdf sdf sdf
for (; (pBuf=strchr(pBuf, ' ')); pBuf++, i++);
return i+1;
}
9:删除字符串中的数字字符
#include <stdio.h>
#include <string.h>
#define SIZE 100
char *deleteNumCh(char *pBuf);//声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("deleteNumCh(buf) = %s\n",deleteNumCh(buf));//函数调用
return 0;
}
char *deleteNumCh(char *pBuf)//定义
{
int i = 0;
int j = 0;
for (i=0; *(pBuf+i); i++){
if ((*(pBuf+i)>='0') && (*(pBuf+i)<='9')){
for (j=i; *(pBuf+j); j++){
*(pBuf+j) = *(pBuf+j+1);
}
i--;
}
}
return pBuf;
}
10:将字符串中连续出现的空格(两个以上)合并成一个
#include <stdio.h>
#include <string.h>
#define SIZE 100
char *deleteSpace(char *pBuf);//定义
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("deleteSpace(buf) = %s\n",deleteSpace(buf));//函数调用
return 0;
}
char *deleteSpace(char *pBuf)//定义
{
char *pBufCp = pBuf;
char *pCp = NULL;
//sdk dfd fgf fgf
for (; (pBuf=strstr(pBuf, " ")); pBuf++){//遍历字符串
for (pCp=pBuf; *pCp; pCp++){//循环前移
*pCp = *(pCp+1);
}
pBuf--;
}
return pBufCp;
}
11:找出字符串中首次只出现一次的字符
#include <stdio.h>
#include <string.h>
#define SIZE 100
char findFirstOneCh(char *pBuf);//声明
int main(int argc, const char *argv[])
{
char buf[SIZE] = "";
gets(buf);
printf("findFirstOneCh(buf) = %c\n", findFirstOneCh(buf));//函数调用
return 0;
}
char findFirstOneCh(char *pBuf)//定义
{
int flag = 0;
int i = 0;
int j = 0;
for (i=0; *(pBuf+i); i++){//遍历字符串
for (j=0, flag=0; *(pBuf+j); j++){//遍历字符串
if (*(pBuf+i) == *(pBuf+j)){//找到出现的字符
flag++;//计数
}
}
if (flag == 1){//找到了
return *(pBuf+i);
}
}
return 0;
}
6:函数参数是指针数组
char *pArr[5];
函数的行参:char *pArr[], int n
函数的实参:pArr, 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM 5
#define SIZE 100
void input(char *pArr[], int n);
void output(char *pArr[], int n);
char *maxBuf(char *pArr[], int n);
int main(int argc, const char *argv[])
{
char *pArr[NUM] = {malloc(SIZE), malloc(SIZE),malloc(SIZE),malloc(SIZE),malloc(SIZE),};
input(pArr, NUM);
output(pArr, NUM);
printf("max = %s\n", maxBuf(pArr, NUM));
for (int i=0; i<NUM; i++){
free(pArr[i]);
}
return 0;
}
void input(char *pArr[], int n)
{
int i = 0;
for (i=0; i<n; i++){
gets(pArr[i]);
}
}
void output(char *pArr[], int n)
{
int i = 0;
for (i=0; i<n; i++){
puts(pArr[i]);
}
}
char *maxBuf(char *pArr[], int n)
{
char *pMax = NULL;
int i = 0;
for (pMax=pArr[0], i=0; i<n; i++){
if (strcmp(pMax, pArr[i]) < 0){
pMax = pArr[i];
}
}
return pMax;
}
5个字符串找出最大的字符串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM 5
#define SIZE 100
void input(char **pp, int n);
void output(char **pp, int n);
void maopao(char **pp, int n);
int main(int argc, const char *argv[])
{
char *pArr[NUM] = {malloc(SIZE), malloc(SIZE),malloc(SIZE),malloc(SIZE),malloc(SIZE),};
input(pArr, NUM);
maopao(pArr, NUM);
output(pArr, NUM);
return 0;
}
void input(char **pp, int n)
{
int i = 0;
for (i=0; i<n; i++){
gets(*(pp+i));
}
}
void output(char **pp, int n)
{
int i = 0;
for (i=0; i<n; i++){
puts(*(pp+i));
}
}
void maopao(char **pp, int n)
{
int i = 0;
char *pTmp = NULL;
int j = 0;
for (j=0; j<n; j++){//冒泡执行的次数
for (i=0; i<n-1; i++){//冒泡
if (strcmp(*(pp+i), *(pp+i+1)) > 0){
pTmp = *(pp+i);
*(pp+i) = *(pp+i+1);
*(pp+i+1) = pTmp;
}
}
}
}
7:函数参数是二级指针
函数的行参:char *pArr[], int n
函数的行参:char **pp, int n
函数的实参:pArr, 5
实现五个字符串的排序
8:函数参数是结构体变量
9:函数参数是结构体数组
12、函数指针和指针函数
函数指针:指针,保存函数的入口地址
函数指针的定义:
int add(int a, int b);
int (*p)(int a, int b) = add;
int *p(int a, int b)
练习:
char *my_stcat(char *p1, char *p2);
char *(*p)(char *p1, char *p2) = my_stcat;
int **fun(int *pa, char **pb, int *p[]);
int **(*p)(int *pa, char **pb, int *p[]) = fun;
#include <stdio.h>
int max(int a, int b)
{
return a>b?a:b;
}
int min(int a, int b)
{
return a<b?a:b;
}
int main(int argc, const char *argv[])
{
//max(3, 5);
int (*p)(int a, int b) = NULL;
p = max;
printf("max(3, 5) = %d\n", max(3, 5));
printf("p(3, 5) = %d\n", p(3, 5));
p = min;
printf("p(3, 5) = %d\n", p(3, 5));
return 0;
}
指针函数:函数,函数的返回值是指针
13、main函数的参数
#include <stdio.h>
int main(int argc, const char *argv[])
{
for (int i=0; i<argc; i++){
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
相关文章推荐
- C语言笔记(六)
- 我的C++学习之路
- C++中字符串的库函数
- C语言笔记(五)
- C语言笔记(四)
- C语言笔记(三)
- C++11(九)
- C语言笔记(二)
- C语言笔记(一)
- 重新学习c++,开启人生新篇章
- VC++/MFC中DoModal
- VS2010进行远程调试C++
- C++第10/11周项目 继承与派生 【是春哥啊】(复习新版)
- C++第10/11周项目 继承与派生 【项目5 - 摩托车继承自行车和机动车】(复习新版)
- C++第10/11周项目 继承与派生 【项目4- 教师兼干部类】(复习新版)
- 深入理解内存对齐
- C++:实现split分割字符串
- [关键字]C/C++中static关键字详解
- C++ 默认析构函数
- C语言ODBC操作MySQL数据库