引言
深入了解C语言的基本元素、计算机存储器结构、常量与变量的概念以及数据类型。这些内容是C语言编程的基础,掌握它们对于编写高效、可靠的嵌入式程序至关重要。
1.C语言的基本元素
编程语言的发展离不开自然语言,所以编程语言的语法和词汇也是由自然语言发展而来,而自然语言的基础是文字,举个例子:想要学会汉语,则必须先学会汉字,想要学会英语,则必须先学会单词,通过下图可以知道,想要学会C语言,必须先学会关键字。
完成一个程序设计的过程就相当于是完成一篇文章的编写,而一篇文章(程序)是由多个段落(函数)构成的,一个段落(函数)是由多个句子(语句)构成的,一个句子(语句)是由多个短语(表达式)构成的,一个短语(表达式)是由多个单词(标识符)构成的,一个单词(标识符)是由多个文字(字符)组成的。
C语言程序由一系列基本元素构成,这些元素包括:
- 字符集:C语言支持的基本字符,包括字母、数字、特殊符号(如
+
、-
、*
等)。 - 关键字:C语言中具有特殊含义的保留字,如
int
、return
、if
等。 - 标识符:由程序员定义的名称,用于表示变量、函数、数组等。
- 运算符:用于执行操作的符号,如算术运算符(
+
、-
)、关系运算符(>
、<
)等。 - 分隔符:用于分隔代码元素的符号,如分号(
;
)、逗号(,
)等。
#include <stdio.h>
int main() {
int a = 10; // int是关键字,a是标识符
int b = 20;
int sum = a + b; // +是运算符
printf("Sum: %d\n", sum); // ;是分隔符
return 0;
}
可以看到,C语言标准中常用的关键字只有32个,并且这些关键字都是小写的,并且都是某些英文单词的缩写。 int -- integer char -- character
2. 计算机存储器结构
数据概念
数据是计算机处理的基本单位,可以是数字、字符、布尔值等。在C语言中,数据通过变量和常量来表示。人类使用计算机的目的就是为了高效的处理大量数据,但是数据的类型有很多,比如声音、图像、文字、数字等,那计算机是如何区分数据的呢? 回答:计算机不用区分,计算机只采用二进制存储。
内存概念
内存是计算机用于存储数据和程序的硬件设备。每个内存单元都有一个唯一的地址,程序通过地址访问内存中的数据。
对于计算机中的存储器而言,一般分为两种:RAM(随机存储器)和 ROM(只读存储器)
(1) 只读存储器
只读存储器的英文全称是Read Only Memory,简称为ROM,属于非易失性存储设备,指的是掉电不丢失数据,可以把数据长时间存储,一般分为很多种,具体的区别可以通过《数电》进行了解,对于计算机的机械硬盘或者固态硬盘而言指的就是ROM。
(2) 随机存储器
随机存储器的英文全称是Random Access Memory,简称为RAM,属于易失性存储设备,指的是掉电会丢失数据,但是读写速度很快。所以一般CPU都是直接和RAM打交道。
内存单位
内存中一个MOS管可以存储一个二进制数0或1,为了方便记忆,标准规定把一个二进制数用bit来进行表示,bit(比特)是binary digit的缩写,中文翻译为位。专业术语一般把一个二进制数称为一位二进制数。所以bit就用来表示计算机数据的最小单位。
注意:计算机处理数据的基本单位是byte,计算机处理数据的最小单位是bit,1byte = 8bit。
内存的单位从小到大依次为:
- 位(Bit):最小的存储单位,表示一个二进制位(0或1)。
- 字节(Byte):8位组成一个字节,是内存的基本单位。
- 千字节(KB):1024字节。
- 兆字节(MB):1024千字节。
- 吉字节(GB):1024兆字节。
#include <stdio.h>
int main() {
int a = 10; // 假设int类型占4个字节
printf("Size of a: %lu bytes\n", sizeof(a)); // 输出a占用的内存大小
return 0;
}
3. C语言的常量与变量
C语言采用常量(Constant)和变量(Variable)作为数据存储的基本单元。从内存管理的角度来看,内存是由连续编址的存储单元构成的物理空间,每个存储单元(8位)都具有唯一的地址标识。虽然理论上可以通过直接寻址方式访问这些存储单元,但由于效率考量,实践中通常采用更高级的抽象访问机制。
根据C语言规范,开发者享有动态内存申请权限。申请过程需遵循以下协议:
- 显式声明所需内存空间的大小(以字节为单位)
- 内核负责在物理内存中定位合适的连续空间
- 系统将分配的内存首地址返回给申请者
为提升内存访问效率,C语言引入了符号化访问机制:
- 开发者可为分配的内存空间指定标识符
- 系统维护符号名与物理地址的映射关系
- 通过符号名实现间接内存访问
基于数据可变性特征,C语言将存储单元划分为两种类型:
- 常量(Constant):程序运行期间值不可变
- 变量(Variable):程序运行期间值可变
常量
常量指的是在程序运行期间值不会发生改变的量,一般使用的数字,比如3.14用来表示圆周率,一般情况下,用户都是用通过宏定义的方式来实现常量的设计,宏定义其实就是简单的文本替换,在预处理阶段预处理器会把程序中的宏定义进行展开。C语言中规定宏定义使用预处理指令 #define 来进行设计。
常量是程序运行过程中值不会改变的数据。常量可以分为以下几种:
- 整型常量:如
10
、-20
。 - 浮点型常量:如
3.14
、-0.5
。 - 字符常量:如
'A'
、'1'
。 - 字符串常量:如
"Hello, World!"
。
变量
变量是程序运行过程中值可以改变的数据。变量指的是在程序运行期间值可能发生变化的量,用户可以根据实际需要来向kernel申请一块存储单元,并对这块存储单元进行命名,然后用户可以随时修改存储单元中的数据。申请的存储单元的大小可以通过C语言中的数据类型进行指定。
命名规则
变量和常量的命名需要遵循以下规则:
- 只能包含字母、数字和下划线(
_
)。 - 不能以数字开头。
- 不能使用C语言关键字。
- 区分大小写。
注意:为了防止二义性出现,C语言标准规定不可以把系统保留字,以及程序中已经存在的函数名称、以及用户已经定义出来的标识符名称作为新的标识符名称(同一个作用域内不能)。
另外:C语言的标识符是区分大小写,并且作为用户而言,标识符的命名应该是有意义的
int myVariable; // 合法
int _value; // 合法
int 1value; // 非法,不能以数字开头
int return; // 非法,return是关键字
4. C语言的数据类型
C语言提供了丰富的数据类型,用于表示不同类型的数据。以下是常见的数据类型:
字符型(char
)
字符型用于存储单个字符,占用1个字节。C语言标准中提供了一个关键字 char ,其实是 character 单词的缩写,表示字符的意思,操作系统char类型的数据宽度定义为1字节,用于存储字符,C语言标准中用单撇号’ ’表示字符。
C语言标准规定:用户打算存储字符 数据宽度 变量名称 ; 举例: char ch = ‘c’ ;
C语言标准中关于字符的种类有两种:普通字符 and 转义字符,对于ASCII码表中转义字符
注意:ASCII码中的转义字符需要使用 ‘\0’ ‘\r’ ‘\n’进行表示,代表字符具有特殊的意义分别表示:空格、换行和回车。
#include <stdio.h>
int main() {
char letter = 'A';
printf("%c\n", letter);
return 0;
}
输出:
A
整数型(int
)
C语言标准中使用关键字int表示整数,整数型用于存储整数值,通常占用4个字节,关键字 int 的英文单词是 integer ,对应的中文具有整数的含义,在32系统下关键字int的数据宽度是4字节,也就意味着存储单元所能存储的整数范围比较广泛。
#include <stdio.h>
int main() {
int number = 100;
printf("%d\n", number);
return 0;
}
输出:
100
短整型(short
)
C语言标准中规定使用关键字 short 来表示短整型,短整型用于存储较小的整数值,通常占用2个字节。一般短整型的全称是 short int ,只不过写程序的时候可以只写 short 即可,在32位系统下 short 短整型占2字节。
#include <stdio.h>
int main() {
short smallNumber = 32767;
printf("%d\n", smallNumber);
return 0;
}
输出:
32767
长整型(long
)
C语言标准中规定使用关键字 long 来表示长整型,长整型用于存储较大的整数值,通常占用4个或8个字节。一般长整型的全称是 long int ,只不过写程序的时候可以只写long即可,在32位系统下 long 长整型占4字节,在64位系统占8字节。
#include <stdio.h>
int main() {
long bigNumber = 2147483647;
printf("%ld\n", bigNumber);
return 0;
}
输出:
2147483647
长长整型(long long
)
C语言标准中规定使用关键字 long long 来表示长长整型,长长整型用于存储非常大的整数值。但是长长整型是使用 long long 来表示,在32位和64位系统下长长整型占8字节。
#include <stdio.h>
int main() {
long long hugeNumber = 9223372036854775807;
printf("%lld\n", hugeNumber);
return 0;
}
输出:
9223372036854775807
浮点型(float
和double
)
数据有整数和小数之分,一般情况下处理的数据也是具有小数的,所以C语言标准中规定使用关键字 float 来表示单精度浮点数,单精度浮点型占4字节,另外C语言标准中也提供了另一个关键字 double 用来表示双精度浮点数,double 占8字节,其实C语言也提供了一种类型 long double,该类型占16字节。
#include <stdio.h>
int main() {
float pi = 3.14;
double precisePi = 3.1415926535;
printf("%f\n", pi);
printf("%f\n", precisePi);
return 0;
}
输出:
3.14
3.1415926535
字符串
字符串是表示某种含义的一个字符序列,字符串在内存是需要一块连续的内存空间进行存储,C语言中规定字符串使用双引号””表示,并且规定字符串的结束标志是’\0’,但’\0’不需要用户手动添加,系统会自动在一个字符串的末尾添加’\0’。
#include <stdio.h>
int main() {
char name[] = "Alice";
printf("%s\n", name);
return 0;
}
输出:
Alice
布尔型(bool
)
用户有时候需要在程序进行判断,在C89标准中,用户如果想要判断某种条件是否成立,一般是定义一个整型变量,然后利用数字0和数字1来表示条件是否成立,用户就可以把变量作为一个标志位使用。 在C99标准可以使用布尔型来表示真假两种情况,头文件 stdbool.h 有相关描述,在头文件中定义了三个宏,分别是 bool、true 以及 false。
#include <stdio.h>
#include <stdbool.h>
int main() {
bool isCodingFun = true;
printf("%d\n", isCodingFun); // 输出1表示true
return 0;
}
输出:
1
补充:
C语言标准中提供了两个关键字 && unsigned用于修饰整数,unsigned表示无符号,signed表示有符号,C语言中的signed修饰符是隐式声明,也就是用户定义整型变量的时候如果没有特别强调,则整型变量默认是有符号的。用户如果要存储无符号的整数,则必须定义变量必须显式声明变量是无符号的(unsigned)。