嵌入式0基础开始学习 ⅠC语言(9)小结补充

这一章呢,来讲一些之前没讲到过的一些点

1.作用域

         什么是作用域?
                一个东西(对象)起作用的范围。
                
                变量的作用域
                函数的作用域
                类型的作用域
            一个c语言工程,可以包含多个.c/.h
            作用域还可以分为
            
                整个工程的作用域
                         在工程的所用文件中,都可以起作用
                本文件的作用域
                          只在本文件中起作用
                函数作用域
                        仅在{}内起作用
                        
        
            a,变量的作用域
                 根据变量作用域的不同,分为如下几类的变量:
                 (1)全局变量:
                               作用域:整个工程作用域
                               定义在函数外面的变量。
                            1.c
                                 int a=5;   // 全局变量
                            2.c  
                                 在2.c中也可以使用1.c的那个a
                                 extern int a.
                
                 (2) 由static 修饰的全局变量(静态全局变量)
                            定义在函数外面的变量,只不过在前面加了一个  static
                            static 修饰全局变量,使得被修饰的全局变量的作用域发生改变
                            变成仅在本文件中生效
                            1.c
                                 static int b = 1024;
                            2.c
                                在2.c中想要使用1.c中的那个b,
                                即使你进行外部声明,那么“呵呵” 做不到了!!!
                                
                 (3)局部变量
                        作用域: 定义在{}内,仅在定义它的那个{}可见
                        func()
                        {
                           int a = 5;
                           if(1)
                           {
                              int b =6; //局部变量
                              printf("a== %d\n",a); // a==5
                           }
                           printf("b==%d\n“,b) ; //ERROR
                        }
                        
            b,函数的作用域
                 (1)整个工程作用域
                         1.c  
                             int sum(int a,int b)
                            {
                                return a+b;
                            }
                        2.c
                            想要使用1.c中sum,
                            需要外部声明,
                            extern int sum(int a,int b);
                  
                  (2)本文件中作用域
                        1.c
                            static int sum(int a,int b)                           
                            {
                               return a+b;
                            }                
                           static 修饰函数,表示被修饰的函数的作用域发生改变,变成仅在本文件中生效
                        2.c
                            在2.c中想要使用1.c中的sum ,即使使用外部声明 ”呵呵“,也做不到

            c,类型的作用域
                   (1)本文件作用域
                            1.c
                                typedef int int32_t;
                                在1.c中都可以使用  int32_t
                            2.c
                                如果在2.c中要使用1.c中的int32_t,则必须在2.c中也要声明定义
                                typedef int int32_t;

                   (2)代码块作用域
                            func1()
                               {
                                typedef unsigned int uint32_t;  
                                    uint32_t仅在定义它的那个{}内可见
                                    
            思考题
                  3.c
                    void func(void);
                    int a  = 5;
                    
                    int main()
                    {
                        int a = 6;
                        
                        if(1)
                        {
                            int a = 7;
                            
                            if(1)
                            {
                                int a = 8;
                                
                                printf("a == %d\n", a); // 8
                            }
                            
                            printf("a == %d\n", a); // 7
                        }
                        
                        printf("a == %d\n", a); // 6
                        
                        func(); // 5
                    }
                    
                        同名不要紧
                        只要域不同。 //域:作用域
                        具体是哪个,
                        往上就近找。 // ”就近原则“

    2生存期

            是指一个对象从生到死的期间。

        随文件系统持续性
             只要一个文件系统存在,那么这个对象就一直存在
        随程序持续性 / 随进程持续性
             进程: 一个正在运行的程序
             是指这个对象,在进程启动的时候,它就存在,并且一直持续到进程消亡。
             进程启动时,就会给那些”随进程持续性“的对象,分配内存空间,并且这个空间
             一直持续到进程消亡。
            
             随进程持续性的对象;
                           全局变量
                           
                           函数
                           
                           static 修饰的全局变量(静态全局变量)
                           
        随代码块持续性
                  是指这个对象,在运行它所属的代码块时,才分配空间给它,
                  并且当这个代码块执行完毕时,它的空间就会自动收回
                   
                  局部变量

     练习:
            分析如下代码的输出结果
            void f (void)
            {
                int a = 7;
                a++;
                printf("%d\n",a);
            }            
            int main()
            {
               f(); //8
               f(); //8
            }
            
            void f(void)
            {
               static int a = 7;
               a++;
               printf("%d\n",a);
            }
            int main()
            {
               f(); // 8
               f(); // 9
            }
            //这句话面试中常常会问到
    static 在c语言中的作用:
            只有两个作用
            (1)static 修饰的全局变量和函数,作用是:
               使得被修饰的全局变量和函数的作用域变为仅在本文件中有效
               
            (2)static 修饰局部变量,作用是:
               使得被修饰的局部变量的生存期,变成了随进程持续性
             

3C语言程序组成

       一个C语言程序是由多个.c和.h组成的
       .c :C源代码文件
       .h :头文件,头文件是干什么用的呢?
      

1. .c文件的组成

      一般来说,.c文件由以下部分组成
      (1)头文件包含部分
            #include : 包含命令
                     作用是把后面的那个文件的内容在此处展开
                    
                     #include <stdio.h>
                     #include "xxxx.h"
                    
                             <>与”“有什么区别?
                                    搜索路径是不一样的
                                    #include 后面只是指定了文件名,
                                    并没有指定搜索的路径,那么我们的编译器到哪里去找呢?
                                    
                                <> :表示到标准的搜索路径下去找   INC_PATH
                                "" :表示先到工程指定的路径下面去找,然后再到标准路径下面去找
                                    如果你没有指定路径的话,默认在当前目录下面找
       
      (2)宏定义 或 声明部分
            宏定义:定义一个宏
                    宏:宏是一个替换别人的东西。
                    宏有两种:
                              a,不带参数的宏
                                    语法;
                                          #define 宏名  要替换的内容
                                          例子:
                                                 #define pi 3.14
                                                 .....
                                        宏的作用:
                                                1)替换
                                                2)增加了代码的可读性
                                                
                              b, 带参数的宏
                                    语法:
                                          #define 宏名(参数列表) 要替换的内容
                                                  参数列表:在宏中的参数,不需要类型的
                                                  使用:
                                                        宏名(实参列表)                                                  
                                            如:
                                                写一个宏,求两个整数之间较大的那一个
                                                #define  MAX(a,b) (a)>(b)?(a):(b)
                                                
                                                main()
                                                {
                                                   int m = MAX(3,4);  
                                                       int m = (3)>(4)?(3):(4);
                                                }    
                                练习:
                                        (1)写一个宏,求数组a的元素个数
                                              #define ARRAY_NUM(a) (sizeof(a)/sizeof(a[0]))
                                                      
                                        (2)写一个宏,取一个整数x中的第n bit。
                                              #define GET_BIT(x,n) ((x>>n)&1)
                                        --------------------------------------------------
                                        
            声明部分:
                      声明:
                            C语言的声明是指把一个符号(名字)与一个对象或类型关联起来
                            告诉编译器,这个符号是个什么东东。

                      为什么要声明?
                            在编译c源文件的时候,是一个文件一个文件编译的,是从第一行到最后一行
                            一行一行进行编译的,遇到一个不认识或没有定义的对象名时,它就会认为这个对象
                            是一个undefine  的东西。

                      外部变量的声明
                            语法;
                                  extern 外部变量的类型 外部变量名;
                  
                                1.c   int a = 5;
                                2.c  需要用到1.c里面a  --->  extern int a;
                       
                      外部函数的声明:
                            语法:
                                  extern 外部函数的返回值类型  函数名(形参列表)
                      
                       类型声明
                                自定义的类型的作用域,最多就是本文件中有效
                                1.c
                                     struct student
                                     {
                                        int num;
                                        int age;
                                        int score;
                                     };
                                2.c 需要用到1.c中的 struct student 该怎么办
                                    只能 ctrl + c  然后  ctrl + v                                
       (3)全局变量和函数定义
                    全局变量:
                             定义在{}外面的变量!!!
                             生存期是随进程持续性,
                             作用域是在整个工程中都有效。
                            
                             int a = 6; // 全局变量
                             int main()
                             {
                                 int b = 6; // 局部变量
                             }                            
                            
                    C源程序是由函数组成的,C语言的指令必须写在函数内部,
                    一个.c文件,可以由多个函数组成,一个工程可以由多个.c和
                    .h组成,一个工程有且仅有一个main函数,这个main函数就是程序的入口
                    main函数结束,程序就执行完毕了。

2.  .h文件组成

        
        一个工程里面可不可以不要.h呢?   可以
        .h 有什么作用呢?
     
            zhangsan.c           wangwu.c
            lisi.c    
            
            int sum(int a,int b)
            {
              return a+b;
            }
            没个用到zhangsan.c中函数或变量或宏定义,都可能需要问zhangsan.c 该怎么用,并且
            我们需要在他们各自的源文件,包括zhangshan的函数或类型
            能不能把我们的一些函数说明,类型说明,变量说明,写成一个接口文件
            需要用到的朋友们,只需要包含我提供给他们的这个接口文件就可以了。
            
            zhangsan.h
              
               struct test
               {
                    char a;
                    int b;
               };
               int sum(int a,int b);
               
            lisi.c
                #include "zhangsan.h"
            wangwu.c
                #include "zhangsan.h"
                
         ==>so, .h 接口描述文件
                包含一些声明:
                             函数声明
                             类型声明
                             外部变量声明
                             宏定义声明
                             ===
                            
                            但是,在头文件中,一般不包含具体代码的实现,它就是一个接口文件
                注意:
                      头文件不能被同一个文件重复包含
                      xxx.h
                          struct nb250
                          {
                              int a;
                              char b;
                          };
                      xxx.c
                         #include "xxx.h"
                         #include "xxx.h"
                        
                        编译器在编译的时候,会将头文件在原地展开
                        ===》
                             struct nb250
                              {
                                  int a;
                                  char b;
                              };
                               struct nb250
                              {
                                  int a;
                                  char b;
                              };
                              
                        在上述程序,不就是重复定义struct nb250 的类型了嘛!!!
                        
                为了防止头文件被重复包含时报错
                头文件的编写规范如下:
                     xxx.h
                            #ifndef __XXX_H__
                            #define __XXX_H__
                                 //...头文件的具体内容
                                       函数声明,类型声明....
                            #endif
                            
                        例子:
                              xxx.h
                                     #ifndef __XXX_H__
                                     #define __XXX_H__
                                          struct nb250
                                          {
                                              int a;
                                              char b;
                                          };  
                                     #endif
                              xxx.c
                                    #include "xxx.h"
                                    #include "xxx.h"
                                ===>
                                         #ifndef __XXX_H__
                                         #define __XXX_H__
                                              struct nb250
                                              {
                                                  int a;
                                                  char b;
                                              };  
                                         #endif
                                        
                                          #ifndef __XXX_H__
                                          #define __XXX_H__
                                              struct nb250
                                              {
                                                  int a;
                                                  char b;
                                              };  
                                          #endif
                                          
                    关于头文件:
                               (1)头文件是一个接口函数
                                        一般只包含一些声明部分
                                        不含代码的具体实现
                               (2)  ”模块化思想“
                                       xxx.c / xxx.h
                               (3)头文件的写法
                                       为了防止头文件被重复包含时报错,头文件的结构一般如下
                                          
                                          #ifndef __XXX_H__
                                          #define __XXX_H__
                                               //......
                                          #endif
                               (4)头文件的引用原则
                                        谁用谁包含
                                        #include "xxx.h"

练习题

1,若  char  str[]="Hello";char *p = str;  那么sizeof(p)=?

(4或8)

2,数组int a[10],编写表达式求数组a的长度(数组中元素的个数)

(sizeof(a))

3,以下for循环的执行次数是for(x=0,y=0;(y=123)&&(x<4);x++)  

(4)

4,有以下程序,执行后的输出结果是?(程序出错)

main()

{

char s[]="abcde";

s+=2;

printf("%d\n",s[0]);bvbb

}

                                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#【进阶】特殊语法

特殊语法、值和引用类型 特殊语法 文章目录 特殊语法1、var隐式类型2、设置对象初始值3、设置集合初始值4、匿名类型5、可空类型6、空合并操作符7、内插字符串8、单句逻辑简略写法 值和引用类型1、判断值和引用类型2、语句块3、变量的生命周期4、结构体中的值和引用5、类中的值…

Hive 常用指标分析

常用指标分析 用户留存率路径分析7日品牌复购率7天内连续三天登录每分钟在线人数 1. 用户留存率 在使用 Hive 统计用户留存率时&#xff0c;我们通常会涉及到两个主要日期&#xff1a;用户注册日期和用户在后续某天的活跃日期。留存率通常是指用户在注册后的某一天仍然活跃的…

重学java 45.多线程 下 总结 定时器_Timer

人开始反向思考 —— 24.5.26 定时器_Timer 1.概述:定时器 2.构造: Timer() 3.方法: void schedule(TimerTask task, Date firstTime, long period) task:抽象类,是Runnable的实现类 firstTime:从什么时间开始执行 period:每隔多长时间执行一次…

内蒙古包头师范学院体育学院车志宏教授

女&#xff0c;汉族&#xff0c;体育学院院长&#xff0c;承担学校体育学、篮球等课程教学工作&#xff0c;曾住持自治区3项科研项目&#xff0c;发表论文5篇&#xff0c;获奖2篇。 1992年天津体育学院体育教育专业&#xff0c;获学士学位&#xff1b; 1998年天津外国语大学体…

fpga问题整理

1、quartus联合modelsim仿真 无波形 问题&#xff1a; modelsim仿真无波形&#xff0c;打开transcript可以看到警告。 警告&#xff1a; # ** Warning: (vlog-2083) f:/program files/altera/ 13.1/quartus/ eda/sim_lib/ altera_lnsim.sv(22728): Carriage return (0x0D) is…

MySQL之Schema与数据类型优化(五)

Schema与数据类型优化 特殊类型数据 某些类型的数据并不直接与内置类型一致。低于秒级精度的时间戳就是一个例子。另外一个例子是一个IPv4地址。人们经常使用VARCHAR(15)列存储IP地址。然而&#xff0c;它们实际上是32位无符号整数。不是字符串。用小数点将地址分成四段的表示…

用AI比赛助手降维打击数学建模,比赛过程详细介绍,这保研不就稳了吗

数学建模是个小众的赛道&#xff0c;可能很多大学生不知道&#xff0c;简单来说&#xff1a;他能薅学分、保研加分、毕业好找工作(简历上写一辈子)&#xff0c;尤其是基于GPT-4o模型&#xff0c;简直对他们是降维打击。 数学建模每年的比赛非常多&#xff0c;像国赛、美赛、深…

asrpro softspi SD卡读写

采样 50M 1M&#xff1b;采样时间足够长&#xff0c;采样频率1M 避免信息遗漏 引脚 cs pa2 mosi pa3 sck pa5 miso pa6 vcc ->5v gnd ->gnd ARDUINO SD库与移植&#xff08;原本是打算移值tw ch32v103的sd库的&#xff0c;但没有对比&#xff0c;只能选择arduino ; …

Keras深度学习框架第二十六讲:使用KerasNLP上传模型

1、上传模型的概念 在机器学习和深度学习领域&#xff0c;"上传模型"通常指的是将训练好的模型保存到某个位置&#xff0c;以便后续使用或分享&#xff0c;而不是直接通过KerasNLP库进行上传操作。但在这里&#xff0c;我们可以理解为保存和分享模型。 当程序员使用…

Java进阶学习笔记22——泛型方法、通配符和上下限

泛型方法&#xff1a; package cn.ensource.d11_generics_method;public class Test {public static void main(String[] args) {// 泛型方法String res test("Java");System.out.println(res);Dog dog1 test(new Dog());System.out.println(dog1);}// 泛型方法pub…

手机上制作证件照

最近由于需要给老姐弄一组证件照&#xff0c;找了一通手机上的软件&#xff0c;找到一款性价比较高的&#xff0c;详细流程记录下来。vx小程序上搜索"泰世茂证件照"&#xff0c;打开首页如下图所示∶ 单击"开始制作" &#xff0c;选择一个证件照类别&#…

Paddle 傅里叶变换基础及领域应用

Paddle 傅里叶变换基础及领域应用 1. 傅里叶变换基础 1.1 傅里叶变换简介 傅里叶变换是一种重要的信号处理技术&#xff0c;它可以将一个信号从时域转换到频域。在频域中&#xff0c;信号的频率特性更加明显&#xff0c;有利于分析和处理。傅里叶变换的基本思想是将一个信号…

基于Rsoft的Fullwave仿真模块进行双芯波导能量耦合与波分复用

Rsoft中的Fullwave仿真模块可以更精确的仿真微小结构&#xff0c;按照建立模型&#xff0c;设置参数&#xff0c;监测能量&#xff0c;优化结构的思路对其进行仿真。图1是在Fullwave模块中建立的双芯波导仿真模型。在模型中设置好折射率、光源、光路、监测器等便可以进行仿真。…

Ubtuntu下安装配置SSH详解

在Ubuntu下安装SSH并配置远程连接&#xff0c;你可以遵循以下步骤&#xff1a; 安装OpenSSH Serve sudo apt update 安装OpenSSH Server&#xff1a; 使用以下命令安装OpenSSH服务器软件包&#xff1a; sudo apt install openssh-server 安装过程可能会要求你确认操作&#x…

Spring STOMP-STOMP客户端

Spring提供了一个基于WebSocket的STOMP客户端和一个基于TCP的STOMP客户端。 首先&#xff0c;你可以创建并配置WebSocketStompClient&#xff0c;如下所示&#xff1a; WebSocketClient webSocketClient new StandardWebSocketClient(); WebSocketStompClient stompClient …

【竞技宝】英超:滕哈格命真硬!足总杯夺冠获欧联资格

足总杯决赛结束,曼联爆冷2比1击败联赛冠军曼城夺冠,滕哈格再一次用顶级理解带队拿到杯赛冠军。赛前曼彻斯特当地有媒体爆料,曼联管理层已经决定要在足总杯决赛之后解雇滕哈格,这个消息让不少球迷都很担心滕哈格的状态。但是荷兰主帅凭借强大的内心,带领球队击败了不可一世的曼城…

如何在Java中创建不可变对象?

在Java中创建不可变对象是一个常见的编程实践&#xff0c;它有助于提高代码的可读性、可维护性和安全性。以下我将从技术难点、面试官关注点、回答吸引力和代码举例四个方面来详细阐述如何在Java中创建不可变对象。 一、技术难点 在Java中创建不可变对象时&#xff0c;主要的…

买房送户口!多城加入“抢人大战”

业内人士认为&#xff0c;近期&#xff0c;多地推出的购房落户政策已区别于此前的人才落户政策&#xff0c;更聚焦于住房消费&#xff0c;降低了落户门槛&#xff0c;体现了各地对导入人口的重视&#xff0c;有利于人才流动&#xff0c;推动新型城镇化建设。 千万人口城市“后…

民宿推荐系统-手把手调试搭建

民宿推荐系统-手把手调试搭建 民宿推荐系统-手把手调试搭建