C语言基础语法-教案11(从小白到劝退之函数)

本文介绍了C语言中函数的概念,强调了作为使用者如何理解函数为黑箱以及设计者如何封装。讲解了函数的定义、参数、返回类型、实参与形参的关系,以及栈内存和局部变量的使用,技术要点包括栈内存限制和函数调用的内存管理。

函数入门

        在C语言中,函数意味着功能模块。一个典型的C语言程序,就是由一个个的功能模块拼接起来的整体。也因为如此,C语言被称为模块化语言。

        对于函数的使用者,可以简单地将函数理解为一个黑箱,使用者只管按照规定给黑箱一些输入,就会得到一些输出,而不必理会黑箱内部的运行细节。

        日常使用的电视机可以被理解为一个典型的黑箱,它有一些公开的接口提供给使用者操作,比如开关、音量、频道等,使用者不需要理会其内部电路,更不需要管电视机的工作原理,只需按照规定的接口操作接口得到结果。

        对于函数的设计者,最重要的工作是封装,封装意味着对外提供服务并隐藏细节。对于一个封装良好的函数而言,其对外提供服务的接口应当是简洁的,内部功能应当是明确的

函数的定义

  • 函数头:函数对外的公开接口
  1. 函数名称:命名规则与跟变量一致,一般取与函数实际功能相符合的、顾名思义的名称。
  2. 参数列表:即黑箱的输入数据列表,一个函数可有一个或多个参数,也可以不需要参数。
  3. 返回类型:即黑箱的输出数据类型,一个函数可不返回数据,但最多只能返回一个数据。
  • 函数体:函数功能的内部实现
  • 语法说明:
返回类型 函数名称(参数1, 参数2, ……)
{
    函数体
}
  • 函数示例1:求两个给定整数的最大值
int max(int x, int y) // 该函数接收两个整型参数,并返回一个整型数据
{
    int z;
    z = x>y ? x : y;
    return z;
} 
  • 函数示例2:交换两个浮点数
void swap(double *p1, double *p2) // 该函数接收两个浮点指针参数,不返回数据
{
    if(p1 == NULL || p2 == NULL)
        return;
        
    double tmp;
    tmp = *p1;
    *p1 = *p2;
    *p2 = tmp;
} 
  • 函数示例3:初始化液晶屏,获取显存入口指针
char * initLCD(void) // 该函数不接受参数,返回一个字符指针
{
    int lcd = open("/dev/fb0", O_RDWR);
    
    struct fb_var_screeninfo vinfo;
    ioctl(lcd, FBIOGET_VSCREENINFO, &vinfo);
    int bpp  = vinfo.bits_per_pixel;
    int size = vinfo.xres * vinfo.yres * bpp/8;
    
   char * fbmem = mmap(NULL, size, PROT_READ, MAP_SHARED, lcd, 0);
   return fbmem;
} 
  • 语法汇总:
  1. 当函数的参数列表为 void 时,表示该函数不需要任何参数。
  2. 当函数的返回类型为 void 时,表示该函数不返回任何数据。
  3. 关键字 return 表示退出函数。①若函数头中规定有返回数据类型,则 return 需携带一个类型与之匹配的数据;②若函数头中规定返回类型为 void,则 return 不需携带参数。

实参与形参

  • 概念:
    • 函数调用中的参数,被称为实参,即 arguments
    • 函数定义中的参数,被称为形参,即 parameters
  • 实参与形参的关系:
    • 实参于形参的类型和个数必须一一对应。
    • 形参的值由实参初始化。
    • 形参与实参位于不同的内存区域,彼此独立。
  • 示例:
// 函数定义中,x、y都属于形参,位于函数 max 的栈内存中
// 它们的值由实参一一对应初始化
int max(int x, int y)
{
    int z;
    z = x>y ? x : y;
    return z;
}

int main(void)
{
    int a = 1;
    int b = 2;
    int m;
        
    // 函数调用中,a、b都属于实参,存储于主函数 main 的栈内存中
    m = max(a, b);    
}

函数调用的流程

  • 函数调用时,进程的上下文会切换到被调函数,当被调函数执行完毕之后再切换回去。

局部变量与栈内存

  • 局部变量概念:凡是被一对花括号包含的变量,称为局部变量
  • 局部变量特点:
    • 某一函数内部的局部变量,存储在该函数特定的栈内存中
    • 局部变量只能在该函数内可见,在该函数外部不可见
    • 当该函数退出后,局部变量所占的内存立即被系统回收,因此局部变量也称为临时变量
    • 函数的形参虽然不被花括号所包含,但依然属于该函数的局部变量
  • 栈内存特点:
    • 每当一个函数被调用时,系统将自动分配一段栈内存给该函数,用于存放其局部变量
    • 每当一个函数退出时,系统将自动回收其栈内存
    • 系统为函数分配栈内存时,遵循从上(高地址)往下(低地址)分配的原则
  • 示例代码:
int max(int x, int y) // 变量 x 和 y 存储在max()函数的栈中
{
    int z;            // 变量 z 存储在max()函数的栈中
    z = x>y ? x : y;
    return z;         // 函数退出后,栈中的x、y 和 z 被系统回收
}

int main(void)
{
    int a = 1; // 变量 a 存储在main()函数的栈中
    int b = 2; // 变量 b 存储在main()函数的栈中
    int m;     // 变量 m 存储在main()函数的栈中,未赋值因此其值为随机值
    
    m = max(a, b);
}

  • 技术要点:
    • 栈内存相对而言是比较小的,不适合用来分配尺寸太大的变量。
    • return 之后不可再访问函数的局部变量,因此返回一个局部变量的地址通常是错误的。
计算机程序设计(C语言教案 " "计算机 "总学时 " " "程序设计 " " " " " " " " " " " " " " "简要回 "讲解实验四 "通过讲解实 " "顾 "复习printf和scanf函数,getchar()和putchar函数的用"验四回顾顺 " " "法 "序结构程序 " " " "设计方法 " "阐述主 "关系运算符和关系表达式 "强调重点和 " "题 "逻辑运算符和逻辑表达式 "难点 " " "条件运算符 " " " "if语句(重点、难点) " " " "switch语句(重点、难点) " " "关系运 "关系运算实际上是比较运算,两个值进行比较,判断比较 "强调关系运 " "算符和 "的结果是否符合给定的条件,如果符合比较的结果为真, "算符中等于 " "关系表 "否则结果为假。 "用==表示, " "达式 "用关系运算符将两个表达式(可以是算术表达式、关系表"注意与=的区" " "达式、逻辑表达式、赋值表达式、字符表达式)连接起 "别 " " "来的式子叫关系表达式。 " " " "关系运算符与其它运算符的优先次序。 " " " "C语言提供六种关系运算符: " " " " < 小于 " " " " <= 小于等于 " " " " > 大于 " " " " >= 大于等于 " " " " == 等于 " " " " != 不等于 " " "逻辑运 "用逻辑运算符将关系表达式或逻辑量连接起来就是逻辑 "强调在逻辑 " "算符和 "表达式。 "表达式的求 " "逻辑表 "逻辑运算符与其它运算符的优先次序。 "解中,并不是" "达式 "逻辑表达式的值应该是一个逻辑量"真"或"假",以数值"1"所有的逻辑 " " ""或"0"表示.而在判断一个量是否为"真"时,以"0"代表假"运算都被执 " " ",以非"0"代表真。 "行。 " " "在逻辑表达式的求解中,并不是所有的逻辑运算都被执行" " " "。 " " " "&&逻辑与 " " " "" "逻辑或 " " " "!逻辑非 " " "实例分 "例:满足下列一个条件即为闰年: 能被4整除,不能被100"通过课堂提 " "析 "整除 能被4整除,又能被400整除. "问,引导学 " " "(year%4= =0&&year%100!=0) " " year%400= =0 "生参与思考 " " "!((year%4= =0&&year%100!=0) " "year%400= =0) " " " "(year%4!=0) " "(year%100= =0&&year%400!=0) " " "条件运 "格式:表达式1?表达式2:表达式3 "强调条件运 " "算符 "条件运算符要求有三个操作对象,称三目运算符,它是c"算符要求有 " " "语言中唯一的三目运算符。 "三个操作对 " " "条件表达式 max= (a>b)? a:b 相当于 "象,是三目 " " "if (a>b) max=a; else max=b; "运算符 " " "说明: " " " "条件运算符的执行顺序 " " " "条件运算符的优先级别,仅高于赋值运算 " " " "条件运算符的结合方向为右结合性 " " " "条件表达式不能取代if语句 " " " "条件表达式中的表达式类型可以不同 " " "实例分 "例:编程,输入一个字符,若是大写就转换成小写;若 "通过例题体 " "析 "不是就不转换,输出字符。main(){char "会条件运算 " " "a;scanf("%c",&a);if (a>='A'&&a<='Z') "符的使用 " " "a=a+32;printf("%c",a);} " " " "//a=(a>='A'&&a<='Z')?a+32:a; " " " "} " " "if "if语句是用来判定是否满足所给定条件,根据判定结果( "分析if语句 " "语句( "真或假)决定执行给出的两种操作之一。 "的三种形式 " "重点、 "if语句的三种形式: " " "难点) " if (表达式) 语句 " " " " if (表达式) 语句1 else 语句2 " " " " if (表达式1) 语句1 " " " "else if (表达式2) 语句2 " " " "else if (表达式3) 语句3 " " " "...... " " " "else if (表达式n) 语句n " " " "else 语句n+1 " " "if语句 "在if语句的内部使用if语句,例如: "if语句的嵌 " "的嵌套 "if ( )if ( ) 语句1else if ( ) 语句2else 语句3 "套,注意与i" " " "f语句的三种" " " "形式的区别
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值