C_函数(精讲)

目录

知识点1【函数的概念】

1、函数的分类:从定义角度分类

2、函数的分类:从参数角度分类

3、函数的分类:从返回值角度分类

知识点2【函数的3要素】

知识点3【函数的传参】(重要)

1、无参的函数

2、int作为函数的参数

函数调用的逻辑

3、数组作为函数的参数

3.1:键盘输入10个int数,寻找出最大值

3.2:键盘输入10个数 分函数完成 数组的排序(冒泡法)

3.3:键盘输入10个数 分函数完成 数组的逆置

3.4:封装函数 实现测量字符串的长度(my_strlen)

3.5: 分装函数完成my_strcpy 字符串拷贝

3.6: 分装函数完成my_strcat 字符串拼接

3.7: 分装函数完成my_strchr 查找第一个字符出现的位置

3.8: 分装函数完成my_str_insert 在指定位置插入字符串

3.9打字游戏

1、获取随机字符串

2、键盘输入字符(不敲回车)

3、获取所耗时间

知识点4【函数的注意事项】(了解)

1、如果函数的返回值类型省略 默认为int (别这样做)

2、如果函数没有参数 请加void修饰 而不是省略不写

使用函数的好处?


知识点1【函数的概念】

1、函数的分类:从定义角度分类

        1.库函数 (c 库实现的)

        2.自定义函数 (程序员自己实现的函数)

        3.系统调用 (操作系统实现的函数)

2、函数的分类:从参数角度分类

        1.有参函数

        2.无参函数

void fun(int x, int y)有参函数
{
    
}

void fun(void)//无参函数
{
    
}

3、函数的分类:从返回值角度分类

void fun(){}
int fun(){}

知识点2【函数的3要素】

函数的定义、函数的声明 、函数的调用

函数的定义:确定函数的返回值类型 函数名 函数的参数 实现函数体 (创建函数)

返回值类型 函数名(函数参数)
{
    函数体;(函数的功能代码)
}

函数声明:说明函数的返回值类型 函数名 函数的参数 注意:不实现函数体(声明函数存在)

extern 返回值类型 函数名(函数参数);

函数调用:执行函数

函数名(如果有参数就传参);

例如:

#include<stdio.h>

//void fun01();//定义和声明在同一源文件中
extern void fun01();//定义和声明可以在同一源文件  也可以在不同源文件

int main(){
    //函数调用
    fun01();//正确的
    //void fun01();//声明语句
    return 0;
}

//函数的定义
void fun01(){
    printf("my_fun01\n");
    return;
}

知识点3【函数的传参】(重要)

1、无参的函数

void fun01(void)//无参的函数 不需要外界传参
{
    
}

调用

fun01();

2、int作为函数的参数

#include<stdio.h>
//函数声明
extern int my_max(int a, int b);

void test01(){
    //需求:键盘输入两个int数据  比较大小
    int data1 = 0, data2 = 0;
    printf("键盘输入两个int数据:");
    scanf("%d %d", &data1, &data2);

    //调用函数实现:获取最大值
    int ret = 0;
    ret = my_max(data1, data2);

    printf("最大值為:%d\n", ret);
}

//函数定义
int my_max(int a, int b){
	return a>b?a:b;
}

int main(){
    test01();
    return 0;
}

函数调用的逻辑

3、数组作为函数的参数

3.1:键盘输入10个int数,寻找出最大值

数组作为函数参数时会被优化为指针变量:int arr[] --->  int *arr

因此不能通过在函数内部对数组形参sizeof来得到数组元素个数,个数只能通过传参得到。

#include <stdio.h>
extern void input_int_array(int arr[], int n);
extern void print_int_array(int arr[], int n);
extern int get_max_from_array(int arr[], int n);
int main(int argc, char const *argv[]){
    //键盘输入10个int数,寻找出最大值
    int arr[10]={0};
    int n = sizeof(arr)/sizeof(arr[0]);

    //封装函数 获取键盘输入
    input_int_array(arr, n);

    //封装函数  输出元素内容
    print_int_array(arr, n);

    //封装函数 获取数组元素的最大值
    int ret = 0; 
    ret = get_max_from_array(arr, n);
    printf("最大值:%d\n", ret);

    return 0;
}

//操作形参中的arr等价操作外部实参的arr
void input_int_array(int arr[], int n){
    printf("请输入%d个int数据:", n);
    int i=0;
    for ( i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    
    return;
}
void print_int_array(int arr[], int n){
    int i=0;
    for ( i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");

    return;
}

int get_max_from_array(int arr[], int n){
    int max = arr[0];
    int i=0;
    for ( i = 1; i < n; i++){
        if(max < arr[i])
            max = arr[i];
    }
    
    return max;
}

3.2:键盘输入10个数 分函数完成 数组的排序(冒泡法)

#include <stdio.h>
extern void input_int_array(int arr[], int n);
extern void sort_int_array(int arr[], int n);
extern void print_int_array(int arr[], int n);
int main(int argc, char const *argv[]){
    
    int arr[10] = {0};
    int n = sizeof(arr)/sizeof(arr[0]);

    //获取键盘输入
    input_int_array(arr, n);

    //排序
    sort_int_array(arr, n);

    //遍历数组
    print_int_array(arr, n);
    return 0;
}
void input_int_array(int arr[], int n){
    printf("请输入%d个int数据:", n);
    int i=0;
    for ( i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    
    return;
}
void sort_int_array(int arr[], int n){
    int i=0, j=0;
    for ( i = 0; i < n-1; i++){
        int flag = 0;
        for ( j = 0; j < n-1-i; j++){
            if(arr[j] > arr[j+1]){
                flag = 1;
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
            }
        }
        if(flag == 0)
            break;//已经有序 不用继续循环
    }
    
    return;
}
void print_int_array(int arr[], int n){
    int i=0;
    for ( i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return;
}

3.3:键盘输入10个数 分函数完成 数组的逆置

#include <stdio.h>
extern void input_int_array(int arr[], int n);
extern void reverse_int_array(int arr[], int n);
extern void print_int_array(int arr[], int n);
int main(int argc, char const *argv[]){
    int arr[10] = {0};
    int n = sizeof(arr)/sizeof(arr[0]);

    //获取键盘输入
    input_int_array(arr, n);

    //排序
    reverse_int_array(arr, n);

    //遍历数组
    print_int_array(arr, n);
    return 0;
}
void input_int_array(int arr[], int n){
    printf("请输入%d个int数据:", n);
    int i=0;
    for ( i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    
    return;
}
void reverse_int_array(int arr[], int n){
    int start = 0, end = n-1;

    while(start < end){
        int cur = arr[start];
        arr[start] = arr[end];
        arr[end] = cur;
        start++;
        end--;
    }
    
    return;
}
void print_int_array(int arr[], int n){
    int i=0;
    for ( i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return;
}

3.4:封装函数 实现测量字符串的长度(my_strlen)

#include <stdio.h>
extern int my_strlen(char buf[]);
int main(int argc, char const *argv[]){
    char buf[128]="";

    //获取键盘输入
    fgets(buf,sizeof(buf), stdin);

    //分装my_strlen
    int len=0;
    len =  my_strlen(buf);
    printf("字符串%s的长度为:%d\n", buf, len);

    return 0;
}
int my_strlen(char buf[]){
    int i=0;
    while(buf[i] != '\0')
        i++;
    return i;
}

3.5: 分装函数完成my_strcpy 字符串拷贝

#include <stdio.h>
void my_strcpy(char buf1[], char buf2[]);
int main(int argc, char const *argv[]){
    char buf1[128]="";
    char buf2[128]="";

    //获取键盘输入
    fgets(buf1,sizeof(buf1), stdin);

    //my_strcpy
    my_strcpy(buf2, buf1);

    //打印
    printf("%s\n", buf2);

    return 0;
}
void my_strcpy(char buf1[], char buf2[]){
    int i = 0;
    while(buf1[i]=buf2[i])
        i++;
}

3.6: 分装函数完成my_strcat 字符串拼接

#include <stdio.h>
void my_strcat(char buf1[], char buf2[]);
int main(int argc, char const *argv[]){
    char buf1[128]="";
    char buf2[128]="";

    //获取键盘输入
    fgets(buf1,sizeof(buf1), stdin);
    fgets(buf2,sizeof(buf2), stdin);

    //my_strcat
    my_strcat(buf2, buf1);

    //打印
    printf("%s\n", buf2);

    return 0;
}
void my_strcat(char buf1[], char buf2[]){
    int i = 0, j = 0;
    while(buf1[i] && ++i);
    while(buf2[j] && (buf1[i++] = buf2[j++]));
}

3.7: 分装函数完成my_strchr 查找第一个字符出现的位置

#include <stdio.h>
int my_strchr(char buf[], char ch);
int main(int argc, char const *argv[]){
    char buf[128]="";

    //获取键盘输入
    fgets(buf,sizeof(buf), stdin);

    char ch = '\0';
    scanf("%c", &ch);

    //my_strcat
    int n = my_strchr(buf, ch);

    //打印
    printf("%d\n", n);

    return 0;
}
int my_strchr(char buf[], char ch){
    int i = 0;
    while(buf[i]){
        if(buf[i] == ch)
            return i;
        i++;
    }
}

3.8: 分装函数完成my_str_insert 在指定位置插入字符串

#include <stdio.h>
#include <string.h>
extern void my_str_insert(char buf1[], char buf2[], int pos);
int main(int argc, char const *argv[]){
    char buf1[128]="";
    char buf2[128]="";
    
    printf("请输入第一个字符串:");
    fgets(buf1, sizeof(buf1), stdin);
    //strlen是测量字符串的长度 不包含'\0'
    buf1[strlen(buf1)-1]='\0';//去掉字符串的中的回车符

    printf("请输入第二个字符串:");
    fgets(buf2, sizeof(buf2), stdin);
    buf2[strlen(buf2)-1]='\0';

    //计算buf1的长度
    int buf1_len=0;
    while(buf1[buf1_len] != '\0')
        buf1_len++;
    
    printf("请输入插入的位置:");
    int pos = 0;
    scanf("%d", &pos);
    if(pos<0 || pos > buf1_len){
        printf("插入位置必须在%d~%d之间\n", 0, buf1_len);
        return 0;
    }

    //字符串的插入函数
    my_str_insert(buf1, buf2, pos);
    
    printf("buf1:%s\n", buf1);

    return 0;
}
void my_str_insert(char buf1[], char buf2[], int pos){
    //1、计算buf2的长度
    int buf2_len = 0;
    while(buf2[buf2_len] != '\0')
        buf2_len++;
    
    //2、将i定位到buf1的'\0'的位置
    int i=0;
    while(buf1[i] != '\0')
        i++;
    
    //3、从buf1的尾部 逐个字符移动 空出合适的位置
    do{
        buf1[i+buf2_len] = buf1[i];
    } while ((i!=pos) && i--);

    //4、将buf2的内容插入到buf1中
    int j=0;
    while(buf2[j] != '\0'){
        buf1[i] = buf2[j];
        i++;
        j++;
    }
    
    return;
 }

3.9打字游戏

1、获取随机字符串

如何产生随机数

#include<stdlib.h>
int rand(void)函数通过返回值返回随机数

//是产生随机数之前 一定要设置随机数种子(基准值)
srand(种子);

将随机数变换成字符

//设置随机数种子
//time(NULL)获取当前时间(1970~现在的所经历秒数)
srand(time(NULL));

char ch = '\0';
ch = 'a'+rand()%26;//rand()函数的返回值就是随机数
printf("ch = %c\n", ch);

将其随机的字符放入字符数组中

2、键盘输入字符(不敲回车)

#include <termios.h>
#include <stdio.h>
#include <unistd.h>

char mygetch( ) {
    struct termios oldt, newt;
    char ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

判断输入正确 字符原样输出 错误输出'_' 统计正确的数量

3、获取所耗时间

第一个字符输入的时候 纪录时间

int start_time = 0;
start_time = time(NULL);

最后一个字符输入的时候 纪录时间

int end_time = 0;
end_time = time(NULL);

所耗时间:end_time -start_time

下面公布一下我自己实现的程序:

#include <time.h>
#include <stdlib.h>
#include "termios.h"
#include <stdio.h>
#include <unistd.h>

extern void game_init();
extern char mygetch() ;
extern void set_str_rand(char *str);
extern int start_game(char *str, int *time);

int main(int argc, char const *argv[]){
    //变量初始化
    int right_time = 0;
    int game_time = 0;
    char str[51] = "";
    int str_count = sizeof(str) - 1;
    char stat = '\0';

    //显示提示信息
    game_init();

    while(1){
        //设置随机字符串
        set_str_rand(str);

        //按下任意键显示字符串
        mygetch();
        printf("%s\n",str);

        //游戏开始
        right_time = start_game(str, &game_time);

        //游戏结束
        printf("\n输入完成!\n");
        printf("用时:%d s\n",game_time);
        printf("正确率:%.2f %%\n",(float)right_time/(float)str_count*100);
        printf("按下ESC退出,空格键继续!\n");
        stat = 0;

        while(stat != ' '){
            stat = mygetch();
            if(stat == 27)
                return 0;
        }
    }
    return 0;
}

void game_init(){
    printf("***************************************************\n");
    printf("*       1、输入过程中无法退出                     *\n");
    printf("*       2、请按所给字母敲击键盘                   *\n");
    printf("*       3、按任意键开始测试,按下首字母时开始计时 *\n");
    printf("*       4、输入出错,打印以_表示                  *\n");
    printf("*       5、按下任意键显示字符串                   *\n");
    printf("***************************************************\n");
}

char mygetch( ) {
    struct termios oldt, newt;
    char ch;
    tcgetattr( STDIN_FILENO, &oldt );
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

void set_str_rand(char *str)
{
    srand(time(NULL));
    int i = 0;
    for(i=0; i<50; i++){
        //str[i] = rand()%('z' - 'a') + 'a';    //小写字母

        //str[i] = rand()%('z' - 'a') + 'A';    //大写字母

        while(!(str[i]>='a' && str[i]<='z') && !(str[i]>='A' && str[i]<='Z'))   //大小写字母
            str[i] = rand()%('z' - 'A') + 'A';

        //while(!(str[i]>='a' && str[i]<='z') && !(str[i]>='A' && str[i]<='Z') && !(str[i]>='0' && str[i]<='9'))   //大小写字母加数字
        //    str[i] = rand()%('z' - '0') + '0';

        //str[i] = rand()%('z' - '#') + '#';    //所有可显示符号
    }
}

int start_game(char *str, int *ti){
    int i = 0;
    int start_time = 0, end_time = 0;
    int right_time = 0;
    //计算字符串总长度
    int str_count = 0;
    while(str[str_count] != '\0' && ++str_count);

    //开始读取键盘信息并记录时间
    for (i = 0; i < str_count; i++){
        char ch = mygetch();
        if(i == 0)
            start_time = time(NULL);
        if(ch == str[i]){
            right_time++;
            putchar(ch);
        }
        else{
            putchar('_');
        }   
    }
    end_time = time(NULL);
    *ti = end_time - start_time;
    return right_time;
}

知识点4【函数的注意事项】(了解)

1、如果函数的返回值类型省略 默认为int (别这样做)

fun01(){
    
}

2、如果函数没有参数 请加void修饰 而不是省略不写

void fun01(void){
    
}
void fun02(){
    
}
#include <stdio.h>
void fun01(void){
    
}
void fun02(){
    //使用不了传递过来的实参
    return;
}
int main(int argc, char const *argv[]){
    //fun01(10,20);//err 不允许传参
    fun01();//ok
    fun02(10,20);//不会报错
    return 0;
}

使用函数的好处?

        1、定义一次,可以多次调用,减少代码的冗余度。

        2、使咱们代码,模块化更好,方便调试程序,而且阅读方便

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值