C 语言的学习(一)简介 编译工具 组成部分 变量 常量 存储类
C 语言简介
C 语言是一种通用的、面向过程式的计算机程序设计语言。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇在贝尔电话实验室设计开发了 C 语言。
C 语言是一种广泛使用的计算机语言,它与 Java 编程语言一样普及,二者在现代软件程序员之间都得到广泛使用。
当前最新的 C 语言标准为 C18 ,在它之前的 C 语言标准有 C17、C11...C99 等。
C 语言是一种通用的编程语言,广泛应用于系统编程、嵌入式开发和高性能计算等领域。
C 语言编译工具
首先我们的实现的时候使用的编译器是我们的 vscode
但是使用这个的时候,我们首先需要先下载一个插件 C/C++ 的插件来实现我们编译 C/C++ 程序
同时实现运行 C/C++ 程序的时候,我们的运行的地方是我们的 集成终端中实现运行我们的程序
C 语言的组成部分
我们的一个 C语言程序包含的部分含有我们的
1.预编译指令
2.函数
3.变量
4.语句 & 表达式
5.注释
#include <stdio.h> int main() { /* 我的第一个 C 程序 */ printf("Hello, World! \n"); return 0; }上面的一个简单的案例就是我们的一个简单的 C 语言的代码的书写格式
main 函数的话,我们是可以发现一点的就是,这个是我们的 C/C++ 程序的默认的入口函数
- 这个代码中的预处理指令就是我们的: #include<stdio.h>
- 函数就是: **int main() **, 整个程序的运行入口就是从这个地方开始实现运行的
- **/ 注释内容 / **每一种编程语言中都是含有这个注释的,注释的内容只是用来实现增加阅读体验的,运行程序时直接忽略
- **printf() **这个就是一个内置函数
- return 0 是一个函数终止的标志
编译以及运行 C程序
当我们实现书写了一个 C 语言程序 hello.c 的时候
这个时候,我们就要开始我们的 编译 & 运行 C 程序
首先我们需要进行的操作就是:
先打开命令提示符(就是终端)
然后运行指令 gcc hello.c
这个时候默认就会生成一个 **a.,out (windows 系统上面是 a.exe) **的可执行文件
然后我们只要进行: ./a.out | ./a.exe
这个时候,就可以实现运行我们的 C 程序了
所以说我们的 C语言程序实现的是先编译然后再运行这两步
因为编译我们的 C 语言程序我们是需要先实现编译,这个时候就需要使用我们的一个编译工具 : gcc
- 使用 gcc 实现编译我们的一个程序的时候,就是使用的是我们的 gcc C程序文件路径
默认生成是我们的 a.out (window 是我们的 a.exe)的可执行文件
然后只要使用我们的 ./a.out 或者 ./a.exe 就可以实现我们的运行这个可执行程序了
同时我们实现使用 gcc 的时候,我们是可以指定输出的内容的 gcc 需要编译的文件名 -o 最终需要运行的文件名
在 liunx 系统上的操作
gcc ./hello.c -o hello.out 生成可执行文件的命令,就是编译的一步
./hello.out 运行可执行文件的一步
在 windows 系统上面的操作
gcc ./hello.c -o hello.exe 实现编译
./hello.exe 运行可执行文件的一步
当后面实现模块化开发的时候,我们这个时候就需要将多个 *.C 文件编译成一个可执行文件
**gcc test1.c test2.c -o main.out(exe) **实现编译
./main.out | ./main.exe
C 语言的基础学习的方式
在C语言中,令牌(token)是程序的基本组成单位,编译器将源码进行词法分析,将源码分解成一个一个的令牌
C语言中的令牌含有:
- 关键字(keywords): 了解过其他编程语言的都知道实际上的话,每种编程语言都是含有属于自己的关键字的
- 标识符(identifiers)
- 常量(Constants): 常量可以理解为是我们的用来存储数据的一种容器,每一种编程语言中都是有常量这一概念的
- 字符串字面量(String Literals)
- 分隔符(Separators)在 C 程序中,分号 ; 是语句结束符,每个语句必须以分号结束,它表明一个逻辑实体的结束。
初入 C 语言
// test1.c #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }// test2.c #include <stdio.h> // 头文件包含 #define PI 3.14159 // 宏定义 // 函数声明 int add(int a, int b); int main() { // 主函数 // 变量声明 int num1, num2, sum; // 用户输入 printf("Enter two integers: "); scanf("%d %d", &num1, &num2); // 函数调用 sum = add(num1, num2); // 输出结果 printf("Sum: %d\n", sum); return 0; // 返回 0 表示程序成功执行 } // 函数定义 int add(int a, int b) { return a + b; }
- test1.c 的代码组成
- 预处理器指令 #include<stdio.h>
- 主函数: 每一个C程序都是含有一个主函数的main()
- 变量声明: 在每一个C程序中我们都是需要自己定义一些变量的
- 自函数定义
test2.h
头文件包含(预处理指令),头文件提供了函数和库的声明, 它们定义了函数、宏、常量等使程序能够使用预定义的库函数
- #nclude<stdio.h>
宏定义: 就是通过我们的 #define 指令来实现的定义我们的常量或者代码片段
- #define PI 3.14159
函数声明
- 函数声明的作用就是先把函数实现声明,然后后面实现其中的具体的功能实现
- 声明提供了函数的返回类型、函数名和参数列表,以便编译器知道如何调用该函数
- int add(int a, int b)
主函数
- 主函数就是一个 C 程序的最终的运行的入口
- main()
函数定义
- 函数定义就是实现的是将我们的声明的函数完善内部的功能代码,这个就是函数的声明
C 语言中的注释
- 一般的资料的话都是说的注释只有两种,实际上注释含有三种书写格式的
- 单行注释: //
- 多行注释: / /
- 文档注释
/** * * */
C 语言数据类型
数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统
C 语言中包含的数据类型含有:
- 基本数据类型
- 枚举类型
- ‘void 类型
- 派生类型
数组类型和结构类型统称为聚合类型。函数的类型指的是函数返回值的类型
整数类型
类型 存储大小 值范围 char 1 字节 -128-127 或者 0-255 unsigned char 1 字节 0-255 signed char 1字节 -128-127 int 2 或者 4 字节 -32,768 - 32,767 或 -2,147,483,648 - 2,147,483,647 unsigned int 2 或者 4 字节 0 - 65,535 或 0 - 4,294,967,295 short 2 字节 -32,768 - 32,767 unsigned short 2 字节 0-65,535 long 4 字节 -2,147,483,648 - 2,147,483,647 unsigned long 4 字节 0 - 4,294,967,295 他表示的值范围的话记忆的方法就是:
1字节等于8位:
- 首先对于我们的 char 类型而言的话,可以表示的就是 28
- 其他的类推即可
- 上面 int 实际上的话是我们的 signed int
- 上面的 long 实际上值得就是我们的 signed long
- 上面的 short 实际上就是我们的 signed short
浮点类型
类型 存储大小 值范围 精度 float 4 字节 1.2E-38 到 3.4E+38 6 位有效位 double 8 字节 2.3E-308 到 1.7E+308 15 位有效位 long double 16 字节 3.4E-4932 到 1.1E+4932 19 位有效位
void 类型
序号 类型和描述 1 函数返回为空C 中有各种函数都不返回值,或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status); 2 函数参数为空 C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void); 3 指针指向 void 类型为 void * 的指针代表对象的地址,而不是类型。例如,内存分配函数 *void malloc( size_t size ); 返回指向 void 的指针,可以转换为任何数据类型。
C 语言 变量
变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。
- 定义变量: type variable_list
- 变量的定义的话,我们首先需要进行的是指定我们的变量是该种存储格式,这个存储格式就是我们的指定数据类型可以这么理解,这个就是 静态类型的语言机制
- type 就是指的是变量的数据类型,包含了整型, 浮点型, 字符型,指针,或者自定义数据类型
- variable_list 指的就是我们的变量列表,就是说明我们定义变量的时候,可以一时间指定多个,使用
,进行隔开即可int agefloat heightchar nameint *ptr- 变量初始化: type variable_list = value_list
- 上面只是定义了我们的变量,但是我们的变量这个小的容器中是没有实际的数据 value 在里面的
int age = 10- 我们进行实现我们的变量的时候,我们
- 定义变量
- 变量初始化
- 或者说定义变量 和 变量初始化一步完成
- 变量不初始化
- 在 C 语言的设计模型中,如果变量没有实现初始化操作,那么最终的效果就是: 默认为 0 的不同形式
- 使用我们的数据类型定义的一个变量的话,是需要建立 存储空间的,这个存储空间等待数据的进入 使用的关键字
extern
C 语言常量
整型常量
整型常量可以是我们的 十进制,八进制,二进制或者十六进制
每一种进制的数据的表示模式都是带有特定的前缀就是表示的是我们的进制了
十六进制的格式为:
- 0x 或者 0X 开头的就是十六进制的表示模式
八进制的表示格式
- 0 开头就是表示的是八进制
十进制表示格式
- 没有任何前缀的就是表示的是十进制
整型常量的表示模式的话可以是使用 U 或者 L 的
- U 表示的是我们的 unsigned
- L 表示的就是我们的 long
- 两个的书写的时候是随意的
浮点型常量
- 浮点型常量的话是由我们的 整数部分,小数点, 小数部分, 值数部分组成的
- 值数部分可以书写我们的 e 或者 E
字符常量 和 字符串常量
- 字符常量就成为了我们平时使用的转义字符
- 字符串常量的话就是实现的是指定一些表现的基本格式即可
定义常量的方法
使用 #define 预处理器 #define 可以在程序中定义一个常量,它在编译时会被替换为其对应的值
- #define variable_name = variable_value
使用 const 关键字 const 关键字用于声明一个只读变量,即该变量的值不能在程序运行时修改
- const type variable_name = variable_value
#include <stdio.h> #define LENGTH 10 #define WIDTH 5 #define NEWLINE '\n' int main() { int area; area = LENGTH * WIDTH; printf("value of area : %d", area); printf("%c", NEWLINE); return 0; } // value of area : 50#include <stdio.h> int main() { const int LENGTH = 10; const int WIDTH = 5; const char NEWLINE = '\n'; int area; area = LENGTH * WIDTH; printf("value of area : %d", area); printf("%c", NEWLINE); return 0; } // value of area : 50两种定义常量的区别
首先这两种都是可以实现定义常量的,但是推荐使用的是 const
因为 使用 const 是具有类型检查以及作用域优势的, #define 只是实现了简单的文本替换
作用域问题:
- #define 是定义的常量是没有作用域限制的,他定义后,在整个代码中都是可以生效的使用
- const 是具有块级作用域的,只是在定义的作用域中才可以实现生效
C 语言 存储类
存储类定义了 C语言中的 变量/函数的存储位置,生命周期和作用域
首先使用存储类只是一些修饰词,一般是在 type 之前实现声明
C 语言中的存储类包括
- auto
- register
- static
- extern
auto 存储类
auto 存储类是所有的局部变量默认的存储类
定义在函数中的变量默认是 auto 存储类,就是说明了这了变量的话,就是在函数开始的时候被创建,函数结束时销毁
int test() { int a = 10; auto int b = 10; return a + b }
register 存储类
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个字),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。
register 存储类定义存储在寄存器,所以变量的访问速度更快,但是它不能直接取地址,因为它不是存储在 RAM 中的。在需要频繁访问的变量上使用 register 存储类可以提高程序的运行速度。
register int age = 16
static 存储类
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁
当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内
全局声明的一个 static 变量或方法可以被任何函数或方法调用,只要这些方法出现在跟 static 变量或方法同一个文件中
静态变量在程序中只被初始化一次,即使函数被调用多次,该变量的值也不会重置
static int count=10;
extern 存储类
extern 存储类用于定义在其他文件中声明的全局变量或函数。当使用 extern 关键字时,不会为变量分配任何存储空间,而只是指示编译器该变量在其他文件中定义
extern 是用来在另一个文件中声明一个全局变量或函数
拓展
什么是静态语言机制,什么是动态语言机制:
1. 从表观上来看的话,静态语言的机制就是实现的是在定义变量的时候,会指定数据类型,
动态类型的语言是不会指定数据类型的
2.但是从实质上来看的话,静态类型的语言机制实际上是在我们定义一个变量的时候就已经
实现了分类了一个固定大小的存储空间
然而动态类型的语言机制的话,就是根据我们的变量值来实现的动态的分配存储的空间的
这个才是真真的 动态类型语言机制 和 静态类型语言机制 的底层机制
动态类型机制语言含有: python javascript...
静态类型的语言: typescript C C++ java Golang rust...