首页 > 其他分享 >C语言07-主函数、函数原型、作用域、static和extern关键字

C语言07-主函数、函数原型、作用域、static和extern关键字

时间:2024-04-08 20:00:12浏览次数:22  
标签:函数 作用域 C语言 int 数组 标识符 常量

第 11 章 函数

11.1 函数的基本概念

1. 什么是函数?
   函数是具有特定功能的代码块

2. 函数的分类
   库函数
   自定义函数

11.2 函数基本语法

① 声明函数(定义函数)

函数四要素:

① 函数名,是标识符,需要满足标识符规范
② 函数体,该函数的代码块,写在 {} 中
③ 返回值和返回类型,返回值作为函数的计算结果
③ 参数,分为形参和实参

注意:强烈不建议函数嵌套声明,C语言也不允许函数嵌套!

② 调用函数

1. 函数名加小括号表示函数的调用,函数只有调用 函数体语句才执行,且每调用一次,函数体都执行一遍
2. 函数调用表达式的值是函数的返回值 

③ 返回值

1. 有返回值: 返回类型与return右边表达式的值的类型一致;如果不一致会发生数据类型转换
2. 没有返回值: ①函数体中没有return语句; ②return的右边是空的;没有返回值的函数需要指定返回类型为 void*
3. return 除了能够设置函数返回值,还可以结束所在的函数

④ 参数

1. 形参
   声明函数时所设置的参数,需要指定数据类型和形参名。形参的本质就是一个函数,只能在函数内部使用。
2. 实参
   调用函数时所给的参数,用于给形参赋值,数量要与形参一致。
eg:形参
// 定义函数
void func(int x)    // x表示的是形参
{
    int num =100;
    const double PI =3.14;
    char msg[]="Hello";

    printf("PI=%.2lf \n", PI);
    printf("msg= %s \n",msg);
}

————————————————————————————————————————————

写法:函数外可以声明定义语句,但不能随便写其他语句

11.3 主函数

① 主函数返回值

C语言约定,主函数返回值0表示运行成功,如果返回其它非零整数,就表示运行失败。

一般主函数会在结尾写:return 0; // 表示运行成功

② 主函数参数(了解)

​ ——main主函数,由系统调用

参数一: 命令选项的数量
参数二: 由所有命令选项组成的数组
eg:
// 定义(声明)主函数, 由系统调用主函数
int main(int argc, char *args[])
{
    printf("Main Function: \n");
    printf("argc=%d \n", argc);
    // 遍历所有的选项
    for (int i = 0; i < argc; i ++)
    {
        printf("%s \n", args[i]);
    }

11.4 函数原型

作用:为了让主函数位置靠前一点,方便读代码

1. C语言中,【函数定义的语句】必须写在【函数调用语句】的前面,否则就用函数原型
2. 如果想把函数定义语句写在调用语句后面,可以在调用语句的前面使用【函数原型】提前声明函数
3. 函数原型需要指定函数的返回类型、函数名、参数类型,不需要设置函数体和参数名字。
	eg:int arr(int);

11.5 作用域

① 作用域的概念

1. 作用域用于确定在代码中某个标识符(如变量、标识符常量、数组等)的可见性和访问范围,它决定了在程序的哪些部分可以引用或访问该标识符。
2. 作用域可以分为全局作用域、局部作用域、块级作用域。
3. 同一个作用域中 不能声明同名 的标识符。

② 全局作用域

1. 在函数和代码块(分支、循环)以外声明的变量、标识符常量、数组等,具有全局作用域,在程序的任何位置都可以被访问
2. 全局的变量、标识符产量、数组,【如果没有初始化赋值】,可以被【自动初始化为0】

③ 局部作用域

1. 在【函数内】定义的变量、标识符常量、数组等,具有局部作用域,作用范围仅限于该函数。
2. 局部的变量、标识符常量、数组,【如果没有初始化赋值】,会得到【垃圾值】,【不会被自动初始化】
	——对于浮点数未被初始化,会得到垃圾值。由于浮点数与整数的存储方式不同,就不能识别01010,所以是0.000 000
	
3. 当使用某个变量(标识符常量、数组等)的时候,先从所在的作用域中查找,如果没有再去上层作用域查找。
4. 函数的上层作用域由【定义函数的位置】决定,与调用函数的位置无关
   C语言标准不建议在函数内嵌套定义函数,函数的上层作用域就是全局。
5. 函数的形参也是局部变量,仅能在所在的函数内使用

④ 块级作用域

1. 在代码块【一个大括号 就是一个代码块】内(分支结构、循环结构、直接写大括号)定义的变量、标识符常量、数组等,具有块级作用域,作用范围仅限于所在的代码块。
2. 具有块级作用域的变量、常量、数组的特性与局部的变量、常量、数组一致,也可以称为局部变量、局部常量、局部数组
 // 循环结构
    for(int i=1; i < 3; i++)
    {
        int age = 100;  // 每次循环都会新建一个age,i还是i
        age ++;
        printf("i=%d,age=%d ",i, age);  // age都=101
    }

⑤ 作用域和内存

内存区域 存放数据
栈区(Stack) 局部变量、局部标识符常量、局部数组等
全局静态区 全局变量、全局标识符常量、全局数组等
堆区 ...
代码区 ...

变量(标识符常量、数组)的生命周期:

局部变量: 函数调用结束就销毁;函数再次调用重新创建。
全局变量: 程序执行结束销毁。

注:只有自行创建的值才需要手动自行销毁

11.6 static 和 extern 关键字

① 静态局部变量

static
eg: static int num;		// 没有初始化自动初始化为0
1. 存储在内存的【全局静态区】
2. 函数调用结束,静态局部变量不销毁,生命周期延长至[程序执行结束]
3. 没有初始化自动初始化为0

注:静态局部变量仍然是局部变量,作用域仍然是所在的函数!!!!

​ ——除了作用域范围没变,其他都和全局变量一致

② 静态全局变量

注: 多文件编译,主函数只能有一个

1. 某个源文件中使用 extern 关键字声明外部链接之后,可以使用其他源文件中定义的全局【变量、标识符常量、数组】
eg:extern int num;		//声明外部文件的标识符

2. 静态的【全局变量、标识符常量、数组】作用范围仅限于所在的源文件,其他源文件即使使用 extern 声明外部链接也无法使用。

③ 静态函数

同静态全局变量

标签:函数,作用域,C语言,int,数组,标识符,常量
From: https://www.cnblogs.com/petard/p/18122424

相关文章

  • C语言面试题之化栈为队
    化栈为队实例要求C语言实现实现一个MyQueue类,该类用两个栈来实现一个队列;示例:MyQueuequeue=newMyQueue();queue.push(1);queue.push(2);queue.peek();//返回1queue.pop();//返回1queue.empty();//返回false说明:1、只能使用标准的栈操作,即只有p......
  • C语言:指针详解(1)
    目录一、内存和地址二、指针变量和地址三、指针变量类型的意义四、const修饰指针五、指针运算六、野指针七、assert断言八、指针的使用和传值调用在正式学习指针之前,我们先要理解在C/C++中两个非常重要的概念——内存和地址。正是有这两种因素的存在,才使得C/C++拥有......
  • c语言多媒体文件管理及检索系统220
     定制魏:QTWZPW,获取更多源码等目录选题程序设计题1:基于数据分析的小区电量扩容推荐程序程序设计题2:神气的盒子程序设计题3:多媒体文件管理及检索系统程序设计题4: 计算24点游戏程序设计题5:上网计费系统模拟程序设计题6:信息产业发展统计程序设计题7:挖地雷程序设计题8:......
  • C语言进阶之动态内存管理【概念篇】
    前言:我们知道C语言是一门接触底层的语言,其核心用法之一就是对内存的操作,本篇将就详细介绍C语言中是如何灵活开辟内存空间的以及如何管理使用这些空间等等。一.为什么要引入动态内存管理 ? 在C语言中我们目前已经掌握两种开辟内存空间的方式:1.intdata=10;//在栈(stack)空......
  • 【C语言】:枚举和联合体
    这里写自定义目录标题1、枚举1.1枚举类型的声明1.2枚举类型的优点1.3枚举类型的使用2、联合体(共用体)2.1联合体类型的声明2.2联合体的特点2.3联合体大小的计算1、枚举1.1枚举类型的声明枚举顾名思义就是⼀⼀列举,把可能的取值⼀⼀列举。⼀周的星期⼀到星期⽇......
  • 经典C语言题目——打印罗汉塔图形
    打印如下图形:++++1+++22++333+444455555点击查看代码#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>intmain(){ inti=0,j=0,k=0; for(i=1;i<=5;i++)//外层循环控制行数 { for(j=1;j<=5-i;j++)//内层循环......
  • 前端【VUE】08-vue【插槽】【默认插槽】【具名插槽】【作用域插槽】
    1、默认插槽默认插槽对应的插槽的名字为default  1、组件目录下components/MyDialog.vue1<template>2<divclass="dialog">3<divclass="dialog-header">4<h3>友情提示</h3>5<spanclass="close......
  • RuleEngine规则引擎底层改造AviatorScript 之函数执行
    https://gitee.com/aizuda/rule-engine-open需求:使用上述开源框架进行改造,底层更换成AviatorScript,函数实现改造。原本实现方式@OverridepublicObjectrun(ExecuteFunctionRequestexecuteTestRequest){IntegerfunctionId=executeTestRequest.ge......
  • 1169: 大整数(指针专题)(c语言)
    题目描述输入3个大整数,位数不超过100位,按从小到大的顺序输出这三个整数。要求定义并使用如下函数比较两个大整数的大小。 intcmp(char*a,char*b) { //若大整数a大于b,返回1; //若a小于b,返回-1; //若a与b相等,返回0 }输入输入有3行,每行输入一个大整数,位数不超过1......
  • 1022: 三整数排序(c语言)
    题目描述从键盘输入三个整数x,y和z,按从大到小的顺序输出它们的值。输入输入三个整数x,y和z。输出按从大到小的顺序输出它们的值。样例输入 201618样例输出 201816#include<stdio.h>intmain(){ intx=0,y=0,z=0; scanf("%d%d%d",&x,&y,&z);......