C语言之函数相关概念

本文详细介绍了C语言中的函数,包括函数的使用场景、定义、基本语法、形参列表、值传递与引用传递、变量作用域以及static关键字的应用。通过示例代码解释了如何通过函数简化代码、提高可维护性,并讨论了全局变量和局部变量的区别,以及static修饰符在全局变量和函数上的影响。
摘要由CSDN通过智能技术生成

为什么需要函数

问题

请大家完成这样一个需求:输入两个数,再输入一个运算符(+,-,*,/),得到结果.。

使用传统的方式解决

//@author:five-five
#include <stdio.h>

int main() {
    // 输入两个数,再输入一个运算符(+,-,*,/),得到结果
    int num1 = 10; //第一个数
    int num2 = 20;//第二个数
    double res = 0.0;//结果
    char oper = '-'; //运算符
    switch (oper) {
        case '+' :
            res = num1 + num2;
            break;
        case '-':
            res = num1 - num2;
            break;
        case '*':
            res = num1 * num2;
            break;
        case '/':
            res = num1 / num2;
            break;
        default :
            printf("你的运算符有误~");
    }
    printf("%d %c %d = %.2f\n", num1, oper, num2, res);
    getchar();
    return 0;
}

传统方式的问题

  1. 代码冗余(即有过多重复的代码)
  2. 不利于代码的维护
  3. 从而引出函数

什么是函数

  1. 为完成某一功能的程序指令(语句)的集合,称为函数。
  2. 在C语言中,函数分为: 自定义函数、 系统函数(查看C语言函数手册)
  3. 函数还有其它叫法,比如方法等,在本视频课程中,我们统一称为 函数。

函数的定义

基本语法

返回类型 函数名(形参列表) {
	执行语句...; // 函数体
	return 返回值; // 可选
}

  1. 形参列表:表示函数的输入
  2. 函数中的语句: 表示为了实现某一功能代码块
  3. 函数可以有返回值,也可以没有, 如果没有返回值,返回类型 声明为 void

注意事项和细节讨论

  • 函数的形参列表可以是多个。

  • C语言传递参数可以是值传递(pass by value),也可以传递指针(a pointer passed by value)也叫引用传递。

  • 函数的命名遵循标识符命名规范, 首字母不能是数字, 可以采用 驼峰法 或者 下划线法 ,比如 getMax()get_max()

  • 函数中的变量是局部的,函数外不生效

  • 基本数据类型默认是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。

  • 如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用(即传递指针)

    //@author:five-five
    #include <stdio.h>
    
    int changeArray(charhello[]);
    
    int main() {
    char hello[]= "Hello";
        printf("%s\n", hello);
        printf("%p\n", &hello);
        char(*pString)[6]= &hello;
        changeArray(hello);
        printf("%s", hello);
    }
    
    int changeArray(charhello[]) {
    		hello[0]= 'A';
        *hello= 'B';
        return 0;
    };
    
    
  • C语言不支持函数重载。

  • C语言支持可变参数函数

函数的传递方式

基本介绍

我们在讲解函数注意事项和使用细节时, 已经讲过C语言传递参数可以是值传递(pass by value), 也可以传递指针(a pointer passed by value) 也叫传递地址或者 引用传递。

两种传递方式

  1. 值传递
  2. 引用传递(传递指针、地址)

其实, 不管是值传递还是引用传递, 传递给函数的都是变量的副本, 不同的是, 值传递的是值的拷贝, 引用传递的是地址的拷贝, 一般来说, 地址拷贝效率高, 因为数据量小, 而值拷贝决定拷贝的数据大小, 数据越大, 效率越低。

值传递和引用传递使用特点:

  1. 值传递:变量直接存储值,内存通常在栈中分配
  2. 默认是值传递的数据类型有 1. 基本数据类型 2. 结构体 3. 共用体 4. 枚举类型
  3. 引用传递:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值)。
  4. 默认是引用传递的数据类型有: 指针和数组
  5. 如果希望函数内的变量能修改函数外的变量, 可以传入变量的地址&, 函数内以指针的方式操作变量(*指针)。 从效果上看类似引用,比如修改结构体的属性.

变量作用域

基本说明

所谓变量作用域(Scope),就是指变量的有效范围

  1. 函数内部声明/定义的局部变量,作用域仅限于函数内部。
  2. 函数的参数, 形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用局部变量(编译器使用就近原则)
  3. 在一个代码块, 比如 for / if中 的局部变量, 那么这个变量的的作用域就在该代码块
  4. 在所有函数外部定义的变量叫全局变量, 作用域在整个程序有效。
void sayHello() {
char name[] = "tom";
	printf("hello %s \n", name);
}
void main() {
	sayHello();
	//这里我们不能使用到sayHello	的name变量
	printf("name= %s", name); //这里将提示,没有定义name
}

初始化局部变量和全局变量

  • 局部变量, 系统不会对其默认初始化,必须对局部变量初始化后才能使用,否则,程序运行后可能会异常退出.

  • 全局变量, 系统会自动对其初始化,如下所示

    数据类型初始化默认值
    int0
    char‘\0’
    float0.0
    double0.0
    pointer 指针NULL

注意事项和细节

  1. 全局变量(Global Variable)保存在内存的全局存储区中,占用静态的存储单元, 它的作用域默认是整个程序, 也就是所有的代码文件,包括源文件(.c文件)和头文件(.h文件) 。
  2. 局部变量(Local Variable)保存在栈中,函数被调用时才动态地为变量分配存储单元, 它的作用域仅限于函数内部。
  3. C语言规定,只能从小的作用域向大的作用域中去寻找变量,而不能反过来,使用更小的作用域中的变量
  4. 在同一个作用域,变量名不能重复,在不同的作用域, 变量名可以重复,使用时编译器采用就近原则.
  5. 由{ }包围的代码块也拥有独立的作用域

static关键字

全局变量使用static修饰

  1. 普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量) ,静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响
  2. 定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用

函数使用static修饰

  1. 函数的使用方式与全局变量类似, 在函数的返回类型前加上static, 就是静态函数
  2. 非静态函数可以在另一个文件中通过extern 引用
  3. 静态函数只能在声明它的文件中可见其他文件不能引用该函数
  4. 不同的文件可以使用相同名字的静态函数, 互不影响

案例

//@author:five-five
#include "stdio.h"

static double num = 1.111;

int create(double param);

int static_incr(void);

static int static_func(double param);

int main(void) {
    puts("测试==============================================\n");
    create(num);
    printf("%f", num);
    puts("测试==============================================\n");
    static_incr();
    static_incr();
    puts("测试==============================================\n");
    static_func(num);
    static_func(num);
    return 0;
}

int static_incr() {
    static int param = 1;
    printf("%i\n", param++);
    printf("%i\n", param++);
    printf("%i\n", param);
    return 0;
}

int create(double param) {
    printf("%f\n", param++);
    printf("%f\n", param++);
    printf("%f\n", param);
    return 0;
}

//无法使用实例方法
static int static_func(double param) {
    printf("%f\n", param++);
    printf("%f\n", param++);
    printf("%f\n", param);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

five-five

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值