当前位置: 首页 > ds >正文

关键字 - 第二讲

本节重点

  • 在多文件中,关于全局变量和函数的一些结论

  • static的作用

  • 如何看待类型

  • 变量的命名规则

  • sizeof的理解

1.3 最名不符实的关键字 - static

先建立2个源文件进行验证,然后提炼出头文件存在的必要性。

认识多文件 - 补充内容

// test.c
int g_val = 10;void show()
{printf("hello files!\n");
}// main.cextern int g_val = 100;// 不可以!声明并没有开辟空间,"=100"叫做初始化!!!但是也不会报错,编译器会自动忽略掉!!!int main()
{show();//会告警!!!system("pause");return 0;
}

test.c 源文件中定义了一个全局变量和一个全局函数;

main.c使用了上面的数据,如果后面有其他的很多源文件也想要使用test.c 中的数据,我们真的要全部声明吗,还有对于函数还会告警的!我们还是需要对函数进行声明的 --- 函数声明这里先放一放。

单纯的使用源文件,组织项目结构结构的时候,项目越大,越复杂的时候,我们的维护成本就会越来越高,为了解决这种问题 --- 头文件出来了!!!(好好看下面代码的注释!!!)

// h: 我们称之为头文件,一般包含函数声明,变量声明,宏定义,头文件等内容(header)
// c: 我们称之为源文件,一般包含函数实现,变量定义等(.c:c语言)// test.h
#pragma once    //防止头文件被重复包含,当前只需要记住,后面会无数次用#include <stdio.h>
#include <windows.h>extern int g_val;// 这个必须带上extern,防止二义性:看成是的定义了
//在 C 语言中,extern 用于声明外部变量(即其他文件中定义的全局变量)void show();
// C 语言的一个特性:函数声明默认具有外部链接性,不需要显式加extern关键字,编译器也会将其视为外部函数(可以被其他文件调用)。//所以在头文件中声明函数时,通常省略extern,写成void show();即可,这是 C 语言的惯例写法。//如果写成extern void show();也完全正确,只是多余的,不会影响程序功能。 --- 建议带上extern//怎么定义就怎么声明,不要一个带参,一个不带参!!!// test.c
#include "test.h" //""包含头文件,目前只需要知道是自己写的头文件,就用""包含即可int g_val = 10;void show()
{printf("hello files!\n");
}// main.c
#include "test.h" //同上int main()
{printf("hello files!\n");system("pause");return 0;
}

全局变量和函数的两个结论 - 补充内容

我们要了解 static ,有几个结论是需要认知清楚的:

变量可以跨文件访问吗?

函数可以跨文件访问吗?

答:

全局变量,是可以跨文件,被访问的。

全局函数,是可以跨文件,被访问的。

这是为什么???

有一定规模的项目,一定是多文件的,多个文件至之间,后续一定要进行数据交互(#include"test.h", main.c -> test.c 函数)如果不能跨文件,交互成本就会比较高,所以设计成全局的化,就可以跨文件访问!

在具体的应用场景,有没有可能,我们不想要让全局变量或者函数跨文件访问,而只想在本文件内部被访问???

这就需要我们的static

1.3.1 修饰变量

修饰全局变量,该全局变量只能在本文件内被使用,不能被外部其他文件直接访问,但是可以是间接的,比如说通过内部的函数带出来。

总结:static修饰全局变量,影响的是作用域的概念,函数类似。而生命周期是不变的。

//test.h文件
void fun1()
{int i = 0;i++;printf("no static: i=%d\n", i);
}
void fun2()
{static int i = 0;i++;printf("has static: i=%d\n", i);
}//main.c文件
int main()
{for (int i = 0; i < 10; i++) {fun1();fun2();}system("pause");return 0;
}
  • 结论:static修饰局部变量,变量的生命周期变成全局周期 --- 随进程了(作用域---{}内不变

  • 另外,这里需要初步讲一下:初始化与赋值的概念。

有些误导性
第1个作用:修饰变量。变量又分为局部变量和全局变量,但它们都存在内存的静态区。
关于C存储布局,我们后面讲到函数会整体来讲,这里不赘述。

static 我们可以理解成为项目维护提供安全保证的!!!

1.3.2 修饰函数

修饰函数,该函数只能在本文中内被使用。

static修饰函数,该函数只能被本文件内被访问,不能被外部文件直接访问,也是同样的道理!

static void fun3()
{static int i = 0;i++;printf("has static: i=%d\n", i);
}void fun3_helper()
{fun3();
}//main.c文件
int main()
{for (int i = 0; i < 10; i++) {fun3();fun3_helper();}system("pause");return 0;
}

1.4 基本数据类型

经过前面的练习,相信同志们对于定义变量并不陌生了。那么此处,我们讲一些其他内容便于大家理解类型。

目前我们只讲内置类型,其他类型我们后面慢慢展开。

C 数据类型

基本类型
数值类型
字符串类型char
数组
结构体struct
共用体union
指针类型
枚举类型emurn
空类型void短整型short
整型int
长整型long
单精度型float
双精度型double

1.4.1 数据类型与"模子"

C常见内置类型:

char
short
int
long
long long
float
double

如何看待数据类型:

前面已经说过,定义变量的本质:在内存中开辟一块空间,用来保存数据。

而定义一个变量,是需要类型的,这个是基本语法决定的。那么,类型决定了:变量开辟空间的大小。

#include <stdio.h>
#include <windows.h>int main()
{//sizeof简单介绍,下个主题就讲printf("%d\n", sizeof(char));    //1printf("%d\n", sizeof(short));    //2printf("%d\n", sizeof(int));    //4printf("%d\n", sizeof(long));    //4printf("%d\n", sizeof(long long));    //8printf("%d\n", sizeof(float));    //4printf("%d\n", sizeof(double));    //8system("pause");return 0;
}

在继续讨论之前,我有一个问题:为什么要根据类型,开辟一块空间,直接将内存整体使用不好吗?

不好。

任何时刻,都不是你一个程序在运行,还有很多其他程序也在运行。你整块用了,让别人怎么办?
另外,你会都用了,一定需要在任何时刻,全部都用完吗?对于暂时不用,但是给你了,对计算机来讲,就是浪费。

那么,问题又来了,我使用部分内存,使用多少由什么决定?其实是由你的场景决定,你的计算场景,决定了你使用什么类型的变量进行计算。你所使用的类型,决定了你开辟多少字节的空间大小。

所以,C语言中,为什么会有这么多的类型?就是为了满足不同的计算场景。

比如,整形计算,字符计算,字符串计算,浮点数计算等。

然后,在回归到书中,关于"模子"的介绍。为了不让同志们感到不适,找了张图。

1.4.2 变量命名规则

min-length && max-information --- 最短长度,最大信息

【规则 1-1】 推荐
【规则 1-2】 推荐
【规则 1-3】 推荐,这个叫做大驼峰命名,具体我看看情况进行对变量命名
【规则 1-4】 推荐
【规则 1-5】 推荐,目前,全局变量可以在变量名前带0...以表示全局含义
【规则 1-6】 暂时不推荐,我们目前关于命名、简单的来
【规则 1-7】 部分推荐,了解一下,目前只要知道全局命名的级别则即可
【规则 1-8】 部分推荐,了解一下
【规则 1-9】 部分推荐,了解一下
【规则 1-10】 推荐
【规则 1-11】 推荐
【规则 1-12】 推荐
【规则 1-13】 推荐
【规则 1-14】 暂时不看,我们后面用的时候再说
【规则 1-15】 推荐
【规则 1-16】 了解
【规则 1-17】 不推荐,还是要看具体场景,转义后面说//目前要求:数字字母下划线,见名知意

记住大驼峰小驼峰,蛇形命名法基本,还有上面的要求就好了!

1.5 最冤枉的关键字 sizeof 理解

1.5.1 常年被误认为函数

int main()
{int a = 10;printf(%d\n,sizeof(a));// 1printf(%d\n,sizeof(int));// 2printf(%d\n,sizeof a);// 3printf(%d\n,sizeof int);// 4return 0;
}

这里那些序号是正确的呢?

4肯定是错的,sizeof 是一个关键字,一个关键字不能直接去求另一个特定的关键字的大小,不带()是不成立的!

那么1,2,3是不是对的呢?是的!sizeof 求特定的一种类型开辟空间的大小是直接有三种做法的!

第三种是可行的,这也就直接证明了 sizeof 不是函数!是关键字/操作符!!!

1.5.2 sizeof(int)*p 表示什么意思

这涉及到指针和数组的区别!

后续再谈!

http://www.xdnf.cn/news/17379.html

相关文章:

  • SpringBoot的优缺点
  • DNS查询过程?CDN是什么,有什么作用?
  • 嵌入式系统学习Day14(C语言中指针的拓展)
  • 音乐创作新潮流!豆包 + 蘑兔 A
  • macOS 彻底卸载 Python 的完整指南
  • RWA项目实战指南:流程设计到技术落地的完整路径
  • 硬件学习笔记--74 电泳与电镀的对比介绍
  • 「iOS」————持久化
  • 安卓Handler和Looper的学习记录
  • 13-netty基础-手写rpc-消费方生成代理-05
  • 30-Hive SQL-DML-Load加载数据
  • 上位机知识篇---蜂窝通信
  • 基于MATLAB实现支持向量机(SVM)分类
  • 目标检测数据集 - 高架视角道路车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • 医疗人效管理新标杆:盖雅工场如何赋能健康服务企业提质增效
  • 从“炼金术”到“工程学”:深度学习十年范式变迁与未来十年路线图
  • 板块三章节4——iSCSI 服务器(待更新)
  • vscode中创建python虚拟环境的方法
  • Rust爬虫与代理池技术解析
  • UDP网络编程chat
  • 腾讯云EdgeOne产品深度分析报告
  • Java 大视界 -- Java 大数据在智能教育在线课程互动优化与学习体验提升中的应用(386)
  • 力扣 hot100 Day67
  • 玩转 InfluxDB 3:用 HTTP API 快速创建高效数据表
  • Java高频方法总结
  • 数据结构(四)内核链表、栈与队列
  • 嵌入式 - 数据结构:栈和队列
  • 大数据之Flume
  • 8.6学习总结
  • Qt菜单栏与工具栏实战