C语言关键字

变量

1. 变量是什么?

变量是内存中一块用来存放数据的空间。所以定义变量的本质是向内存申请一块空间用来存放数据。

2. 变量的初始化和赋值
#include<stdio.h>
int main()
{
    int a = 10; //初始化:只能初始化一次,因为该空间只开辟一次。
    a = 20; //赋值:可以多次重复赋值。
    
    return 0;
}

3. 为什么要定义变量

计算机的出现的根本是为了解决人的计算能力不足,那么在计算机计算的时候就需要处理大量的数据。但是计算机也是一步一步计算数据的,那么数据的计算肯定有先后之分,并且为了保证在计算数据的时候能够方便的拿到数据,计算机会把数据放到内存中使用。总结:因为有数据需要暂时的被存储起来,所以我们需要用变量来保存它来等待计算机对它进行后续处理。

4. 变量的生命周期

  • 生命周期概念:指该变量从定义到被释放的时间范围,所谓的释放,指的是内存中空间的“释放”。
  • 局部变量:进入代码块,产生局部变量(会开辟空间),退出代码块,销毁局部变量(释放空间)。
  • 全局变量:定义完成之后,程序运行的整个生命周期内,该变量都一直有效。
  • 变量的作用域是“空间”上的概念,生命周期是变量的“时间”上的概念。

一、auto

  1. 使用:一般在代码块中定义的变量,即局部变量,默认都是auto修饰的,不过一般都是省略。
    #include<stdio.h>

//auto int i = 100;
//全局变量,不能使用 auto 关键字

int main()
{
    auto int a = 10;//局部变量,可以使用。
    
    for (auto int i = 0; i < 10; i++)
    { // 临时变量,也可以使用。
        ;
    }
    
    return 0;
}
  1. 默认所有的变量都是auto修饰吗?
    答:不是,一般只是用来修饰局部变量(局部变量、自动变量、临时变量都差不多,我们统称为“局部变量”)
  2. 总结:auto 关键字太老了,现在基本不用,可以不写。

二、register

  1. 基本知识普及
  • 计算机的存储结构是采用“存储分级”的形式来对我们的存储单元进行组织的。CPU是主要用来进行计算的硬件单元。为了方便运算,一般第一步需要先把数据从内存中读取到CPU内,那么这就要求CPU需要具有一定的数据临时存储能力,所以,在现代CPU内,都集成了一组叫做“寄存器”的硬件,用来做临时数据的保存 。
  • CPU会在执行计算操作前预先把特定数据读取到CPU内,提高计算机运算效率。
    暂时无法在飞书文档外展示此内容
  1. 作用
    当你使用register来操作一个变量的时候,你只是在向编译器提出“建议”,把这个变量放到CPU的寄存区中,而编译器也尽量将变量放到CPU寄存区中,用来以提高计算效率 。注意,并不是用了register关键字,编译器就一定会帮你把你定义的变量放到CPU的寄存区中去,而是取决于编译器本身。另外,register并不会影响变量的生命周期 。
  2. 适用范围
  3. 局部的变量。(全局变量会导致CPU寄存器被长时间占用)
  4. 不会被写入的变量。(写入就意味着要写回内存,后序还要读取检测的话,register就没有意义了)
    暂时无法在飞书文档外展示此内容
  5. 高频被读取的变量。(可以节省大量时间)
  6. 不能大量使用,寄存器的数量是有限的。
  7. 被rigister修饰的变量不能够取地址(此时的变量是存放在寄存区中的,而地址是找到的内存空间),但是可以修改变量的值。
#include<stdio.h>

int main()
{
    register int a = 10;
    //示例一
    printf("&a = %p\n",&a);//err
    //VS2022会报错:error C2103: 寄存器变量上的“&”
    //当然,不是所有的编译器都会报错,这个后续再补充。
    
    //示例二
    a = 20;//ok
    printf("%a = d\n",a);// a = 20;
    
    return 0;
}
  1. 总结:早期的编译器需要人为指定register来进行手动优化,不过现在编译器很智能,能够进行比人更好的代码优化。所以,不用管该关键字 。

多文件

  1. main.c
#include<stdio.h>

extern int g_val;
//这是个声明,表明引用的是其他文件(test.c)的变量。
extern int g-val = 200;
//这种情况就不是声明,而是在定义一个整型全局变量g-val,并且赋初值为200。
//VS2022实测报警:或上一个增量链接没有生成它;正在执行完全链接test.obj : error LNK2005: _g_val 已经在 main.obj 中定义
//这表明程序在执行链接时出错。
//警告:fatal error LNK1169: 找到一个或多个多重定义的符号
//因为g_val这个变量在test.c和main.c两个文件内都定义了,所以是“重定义”

int main()
{
    show();//使用其他文件内的函数
    //在不进行声明的情况下也可以运行。但是在有些编译器上会报警告;
    //用VS2022测试: warning C4013: “show”未定义;假设外部返回 int
   
    return 0;
}
  1. test.c
#include<stdio.h>
//因为此文件中使用了printf函数,所以要包含对应的头文件

//函数,可以视作全局的
void show()
{    
    printf("Hello World!");
}

int g_val = 10;//全局变量

当我们写一个大的项目的时候,会用到许多自己写的函数,这个时候再使用这种extern??的方法未免太过麻烦,所以就诞生了“头文件”。
3. main.h

#pragma once

//头文件中应该放的内容:
//1. C头文件
//2. 所有变量的声明
//3. 所有函数的声明
//4. #define、类型typedef还有struct

extern int g_val;   //变量声明必须带上extern
extern void show(); //函数声明建议带上extern

好,总结一下为什么要有头文件:

  • 单纯的使用源文件来组织项目结构的时候,随着项目越来越大、越来越复杂的时候,维护成本就会越来越高。所以使用头文件来组织项目结构,就可以有效的减少大型项目的维护成本问题。
  • 但是这也会造成另一个问题:头文件被重复包含的问题。要解决这个问题,方案一就是在头文件中写上:#pragma once就能避免头文件被多次包含的问题。

笔记使用飞书写的,挪到csdn上有点不好看,等我再写点,就把飞书文档给你们看。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值