嵌入式八股—C语言入门学习(一)

本章学习:C语言的运行机制、常见的库文件、代码框架、标识符的命名规则、C语言关键字、常量学习、输入输出函数、局部变量与全局变量

一、C语言运行机制

整个过程:编写.C文件、编译成.obj的二进制机器指令、结合C语言的库文件链接形成可执行的二进制.exe、最终运行输出结果。

C语言常见的库文件有:

头文件 常用函数 / 内容 高频考点
<stdio.h> printf、scanf、fopen、fread、fwrite 输入输出、文件操作
<string.h> strlen、strcpy、strncpy、memcpy、memset、strcmp strcpy 与 memcpy 区别、越界风险
<stdlib.h> malloc、calloc、realloc、free、atoi、exit、qsort、bsearch malloc 底层、内存泄漏
<math.h> sqrt、pow、sin、abs(需链接 -lm) 编译时记得加 -lm
<ctype.h> isdigit、isalpha、toupper、tolower 字符分类
<time.h> time、clock、gettimeofday(POSIX) 计时、时间戳
<assert.h> assert() 调试断言
<errno.h> errno、perror、strerror 错误码处理
<stdarg.h> va_list、va_start、va_end 可变参数实现
<stdint.h> int8_t、uint16_t、int32_t 嵌入式必考:定长整型,跨平台 / 跨 MCU 可移植
<stdbool.h> true、false C99 后可用布尔类型
<limits.h> INT_MAX、CHAR_BIT 等 各类型取值范围
<stddef.h> NULL、size_t、ptrdiff_t、offsetof 常见宏定义
<setjmp.h> setjmp、longjmp 异常跳转(低层)

基本的代码框架:

cs 复制代码
#include<stdio.h> //C语言的编译头文件库
int main()  
//每一个程序(或工程)可以定义很多函数(后面讲),但有且只有一个main()函数,作为程序执行的入口,空括号(),表示 main 不接受任何参数。
//写在main之前的"int"称为关键字,代表数据类型是整型。它是main()的返回值类型。即在执行main()函数后会得到一个整型值,无返回值可定义void类型
{

    return 0;//int数据类型下不能省略
}

注意:(1)其中一对花括号{}定义了函数的主体,所有函数都必须以大括号开头和结尾,成对出现。
(2)每一个执行语句后面都会有一个英文分号"
;
"作为语句结束的标志。
C语言的输出格式:printf()
printf()函数是产生格式化输出的函数,作用是将参数文本输出到屏 幕。它名字里面的 f 代表 format (格式化),表示可以指定输出文本的格式。printf() 是在标准库的头文件 stdio.h 中定义的。要想在程序中使用这个函数,必须在源文件头部引入这个头文件。

其中:占位符的第一个字符是% ,第二个字符表示占位符的类型。printf() 的占位符有许多种类,与 C 语言的数据类型相对应。其中常见的类型输出格式为int(%d)、char(%c)、float(%f)、八进制整数(%o)、十六进制(%x)、String字符串(%s)、科学技术法(%e)等等;

二、C语言的变量命名规则

C语言中变量、函数、数组名、结构体等要素命名时使用的字符序列,称为标识符

标识符组成由:字母、数字、下划线_,但是命名规则必须是字母或者下划线_为开头;变量名不能有空格且不能为关键字(下面会讲);

其中长度也有限制:

C89标准规定标识符长度不得超过31个字符。
C99标准规定标识符长度不得超过63个字符。

注:标识符如果超出编译器所支持的标准就会忽略后续的字符长度;

传统的C语言常见关键字有32个:

|---------------|------------------------------------------------------------------------------------|
| 类型 | 具体关键字 |
| 控制语句关键字(12 个) | break, case, continue, default, do, else, for, goto, if, return, switch, while |
| 数据类型关键字(12 个) | char, enum, double, long, float, int, short, signed, struct, unsigned, union, void |
| 存储类型关键字(4 个) | auto, extern, register, static |
| 其他关键字 (4 个) | const, sizeof, typedef, volatile |
[C语言常见关键字]

后续,1999年,C99标准增加了5个关键字: inline 、 restrict 、 _Bool 、 _Complex 和 _Imaginary 。 2011年,C11标准又增加了7个关键字: _Alignas 、 _Alignof 、 _Atomic 、 _Static_assert 、 _Noreturn 、 _Thread_local 和 _Generic 。
其中C语言的变量名的命名最好是有意义的定义,这有助于代码的可读性和维护性;

2.1 变量的的作用:

变量是程序中不可或缺的组成单位,最基本的存储单元;一个变量就是一个存储单元,就会分配存储空间;
变量的定义一般按照以下的格式进行

数据类型 变量名; //声明变量的语句必须以分号结尾、

举例:

int length;

char ID;
C语言常见的数据类型如下所示:

bash 复制代码
//基本数据类型【整型、浮点型、字符型】
整型int、短整型short int、长整型long int
浮点型可分为:单精度型float、双精度型double
字符型:单字节char、字符串则用字符数组表示

//构造类型
数组类型、结构体类型struct、共用体类型union、枚举类型enum

//空类型 void

//指针类型 *

三、C语言的常量

常量在程序运行过程中其值不能被修改,是 C 语言中最基础的数据形式之一。按照书写形式和使用方式,常见的常量可以分为以下几类。

3.1 字面常量(直接常量)

直接写在代码中的具体数值或字符,不需要额外定义即可使用。

  • 整型常量 :如 100、-25、0。可以写成十进制、八进制(以 0 开头,如 0755)或十六进制(以 0x 开头,如 0xFF)。

  • 实型(浮点)常量 :如 3.14、-0.5,也支持科学计数法 1.2e3(即 1200.0)。默认是 double 类型,加后缀 f 表示 float,如 3.14f。

  • 字符常量 :用单引号括起来的单个字符,如 'A'、'9'、'\n'。字符常量在内存中存储的是其 ASCII 码值,因此 'A' 等价于 65。

  • 字符串常量 :用双引号括起来的字符序列,如 "hello"、"C语言"。字符串末尾会自动添加结束符 '\0',所以 "abc" 实际占用 4 个字节。

3.2 转义字符常量

以反斜杠 \ 开头的特殊字符,用于表示无法直接输入的字符。

转义字符 含义
\n 换行
\t 水平制表符(Tab)
\\ 反斜杠本身
\' 单引号
\" 双引号
\0 空字符(字符串结束标志)
\ddd 三位八进制数表示的字符,如 \101 表示 'A'
\xhh 十六进制数表示的字符,如 \x41 表示 'A'

3.3 宏常量(符号常量)

使用 #define 预处理指令定义的常量,在编译前由预处理器进行文本替换,就是用一个标识符来表示一个常量值。宏名用大写字母表示,以便于与变量区别;

格式:#define 符号常量名 常量值

c 复制代码
#include <stdio.h>

#define PI 3.14159
#define MAX_SIZE 100

int main(void)
{
    double r = 2.0;
    printf("面积 = %f\n", PI * r * r);
    printf("最大容量 = %d\n", MAX_SIZE);
    return 0;
}

注意: 跟#include一样,"#"开头的语句都是"预处理语句",在编译之 前,预处理器会查找程序中所有的"PI ",并把它替换成3.14159,这 个过程称为预编译处理。宏常量只是简单的文本替换,没有类型检查,因此建议在定义时加上括号,避免运算优先级问题,例如 #define SQUARE(x) ((x) * (x))。

3.4 const 修饰的常量

C99中新的声明方式,这种方式跟定义一个变量是一样的,只需要在变量的数据类型前再加上一个const关键字,这被称为"限定符"。使用 const 关键字修饰的变量,其值在初始化后不能被修改,具有类型检查,是更推荐的常量定义方式。

格式:const 数据类型 常量名 = 常量值;

c 复制代码
#include <stdio.h>

int main(void)
{
    const double PI = 3.14159;
    const int MAX_SIZE = 100;

    printf("PI = %f\n", PI);
    printf("MAX_SIZE = %d\n", MAX_SIZE);

    // PI = 3.14;  // 编译错误:const 变量不能被修改
    return 0;
}

const常量与宏常量的区别:

  • const 常量有数据类型,编译器会进行类型检查;宏常量只是文本替换。
  • const 常量在调试时可以看到变量名和值;宏常量在预处理后已不存在。
  • const 常量占用内存(可能被优化),宏常量不占用内存。

3.5 枚举常量

使用 enum 关键字定义的一组有名字的整型常量,适合表示一组相关的状态或选项。

c 复制代码
#include <stdio.h>

enum Weekday {
    MON = 1,
    TUE,
    WED,
    THU,
    FRI,
    SAT,
    SUN
};

int main(void)
{
    enum Weekday today = WED;
    printf("today = %d\n", today);  // 输出 3
    return 0;
}

枚举常量的值默认从 0 开始依次递增,也可以手动指定初始值,后续未指定的成员会在此基础上继续递增。

3.6 常见常量对比

常量类型 定义方式 特点
字面常量 100、3.14、'A' 直接书写,无需定义
宏常量 #define PI 3.14 预处理替换,无类型检查
const 常量 const int N = 10; 有类型检查,推荐使用
枚举常量 enum Color { RED, GREEN }; 一组相关的整型常量

小结: 在实际开发中,对于简单的数值常量优先使用 const 定义,既能保证类型安全,又便于调试;对于需要表示一组相关状态的场景,使用 enum 更加清晰;宏常量则多用于条件编译或需要跨文件共享的配置项。

四、C语言的输入输出

所谓输入输出是以计算机主机为主体而言的。输出:从计算外部输出设备(显示器、打印机)输出数据。输入:从输入设备(键盘、鼠标、扫描仪)向计算机输入数据。

C语言本身没有提供专门的输入输出语句,所有的输入输出都是由调用标准库函数中的输入输出函数来实现的。常用的输入输出函数如下所示:

输入函数:scanf() 、 getchar()、gets():

scanf(),是格式输入函数,可接收任意类型的数据。

getchar(),是字符输入函数, 只能接收单个字符。

gets(),是字符串输入函数。

输出函数:printf() 、 putchar()、puts():

printf(),是格式输出函数,可按指定的格式显示任意类型的数据。

putchar(),字符显示函数,只能显示单个字符。

puts(),是字符串输出函数。

4.1 scanf()的使用

scanf()函数的作用:把从键盘上输入的数据根据找到的地址存入内存中,即给变量赋值。

格式为:scanf("格式控制字符串",参数地址列表);

格式控制字符串:约定输入数据的类型和格式,参数的个数必须与变量地址的个数一致。

参数地址列表:以逗号 ", "分隔的、输入数据变量地址序列。

例如:scanf("%d%d%d",&a,&b,&c);%d表示类型的输出格式、&表示取地址符号

注意:

如果scanf中%d是连着写的,如"%d%d%d",在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔。即"2(空格)3(tab)4" 或 "2(tab)3(回车)4"等。

如果是"`%d,%d,%d`",则在输入数据时需要加","逗号,如"2,3,4"。

4.2 getchar()、putchar()的使用

getchar():输入字符数据

格式:getchar()

功能:从键盘缓冲区读入一个字符

putchar():输出字符

格式: putchar(ch),其中ch是一个字符变量

功能:从标准输出设备输出一个字符

4.3 gets()与puts()的使用

puts():在C语言中,puts() 是一个用于输出字符串的标准库函数,其原型定义在标准头文件中。puts() 函数的作用是将一个以 null 字符(\0)结尾的字符串打印到标准输出(通常是控制台)上,并自动添加一个换行符。

注意,puts()函数只能用于输出字符串,而不能输出其他类型的数据。如果需要输出其他类型的数据,应使用 printf() 函数。

gets():读取标准输入设备输入的字符串,直到遇到【Enter】键才结束。

补充:也可以用printf()函数输出打印;

样例代码为:

cs 复制代码
#include<stdio.h> //puts头文件需要

int main() {

    char str[15];
    printf("enter your name:");
    gets(str);        //输入字符串至数组变量str
    printf("your name is ");
    puts(str);        //输出字符串
    printf("your name is %s\n",str);  //输出字符串
    return 0;
}

五、局部变量与全局变量

变量按照声明的位置,可以分为:局部变量 和 全局变量。

局部变量: 在函数体内{}定义的变量,也称内部变量。局部变量只能在定义它的函数中使用。

全局变量 :在函数之外{},定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。

一个程序中,凡是在全局变量之后定义的函数,都可以使用在其之前定义的全局变量;当局部变量和全局变量同名的时候,局部变量优先使用。

cs 复制代码
#include <stdio.h>

int global = 2026;//全局变量
int main(){

    int local = 2026;//局部变量
     //下面定义的global会不会报错?
    int global = 2026;//局部变量
    printf("global = %d\n", global);
    return 0;

}

总结:

本章初步了解了C语言的运行机制,了解了C语言中变量的命名、输入输出函数。下一章节直接针对性学习C语言的结构,可能减少部分原理性知识;

相关推荐
沐晓时光2 小时前
C语言入门,字符串和字符串函数知识讲解
c语言·开发语言
Funlang3 小时前
Fun 语法三则:花括号、块尾分号、点号后的关键字
编程语言
codigger7 小时前
2026年,AI PC靠什么反超传统PC?
ai·大模型·编程语言
智者知已应修善业8 小时前
【51单片机实现从下到上,从上到下,从中间到两边,两边到中间】2024-10-23
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
布莱克60517 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
Patrick_Wilson20 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言
Patrick_Wilson21 小时前
从文本输出理解 Go 方法与接口
后端·go·编程语言
揽星河..21 小时前
【C语言】底层程序设计
c语言·开发语言
揽星河..1 天前
【C语言】结构体
c语言·开发语言