硬核整理 | 手把手教你轻松入门C语言,C语言必备基础一网打尽,入门就能上手项目!

目录

1. stdint.h 简介

2. 位操作

3. 宏定义

4. 条件编译

5. extern 声明

6. 类型别名 typedef

7. 结构体

8. 指针

9. 代码规范

实践建议:


1. stdint.h 简介

stdint.h 是 C99 标准引入的一个头文件,提供了固定宽度的整数类型,提高了代码的可移植性和可读性。常见类型包括:

注意:使用前要开启C99模式哦,以keil 5为例说明 如下图:

2. 位操作

位操作是直接对二进制位进行操作的技术,在嵌入式系统中常用于寄存器操作、标志位管理、节约存储空间等。

  • 基本操作:
    • 与(&):将某位清0
    • 或(|):将某位置1
    • 异或(^):将某位取反
    • 取反(~):按位取反
    • 左移(<<)、右移(>>):移位操作,左移相当于乘以2,右移相当于除以2(无符号数)

以下为示例代码

GPIOA->ODR |= (1<<5);   // 将GPIOA的输出数据寄存器第5位置1(假设控制LED的引脚)
GPIOA->ODR &= ~(1<<5);  // 将第5位清0
GPIOA->ODR ^= (1<<5);   // 将第5位翻转

实用技巧:

  • 设置某一位:x |= (1 << n);

  • 清除某一位:x &= ~(1 << n);

  • 翻转某一位:x ^= (1 << n);

3. 宏定义

宏使用 #define 定义,常用于常量定义、条件编译、简化代码等。

示例:

#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))   // 注意:带参数的宏,参数要用括号括起来
  • 注意事项:
    • 宏只是文本替换,不进行类型检查。
    • 在定义函数式宏时,要注意参数可能产生的副作用(比如多次计算),以及括号的使用(避免运算符优先级问题)。

4. 条件编译

条件编译可以根据宏控制编译的内容,适用于平台区分、调试开关等。

常见指令:

#define DEBUG 1

#if DEBUG
// 调试代码
#endif

另一个常见用途:防止头文件重复包含(在每个头文件的开头和结尾):

#ifndef __MYHEADER_H__
#define __MYHEADER_H__
// 头文件内容
#endif

5. extern 声明

extern 用于声明在其他源文件中定义的变量或函数。

  • 声明但不定义变量(避免重复定义):

示例:

// file1.c
int counter = 0;

// file2.c
extern int counter;  // 告诉编译器:这个变量在别处定义

6. 类型别名 typedef

typedef 用于为已有类型创建新的类型名,提高可读性和移植性。

示例:

//第一种情况
typedef unsigned char uint8_t;   // 定义uint8_t为无符号8位整数
//第二种情况:
typedef struct {
    int x;
    int y;
} Point;                        // 定义Point为结构体类型

  • 在STM32库中大量使用typedef来简化结构体类型,如GPIO_TypeDef

7. 结构体

结构体是用户自定义的数据类型,用于组织不同类型的数据。

struct person {
    char name[20];
    int age;
    float height;
};
struct person p1;   // C语言中需要写struct关键字
// 或者使用typedef来避免写struct:
typedef struct {
    char name[20];
    int age;
    float height;
} Person;
Person p2;

8. 指针

指针是 C 的核心特性,指向某种类型数据的内存地址。

以下是指针使用的2个最常见问题:

  • 基本操作:
    • 定义:int *p;
    • 取地址:int a; p = &a;
    • 解引用:*p = 10;(将10赋值给a)
  • 在嵌入式开发中,指针常用于直接访问硬件地址(如寄存器映射)、传递大结构体(避免复制)等。
  • 示例:通过指针访问GPIO寄存器(在STM32中,外设寄存器被映射到固定地址)
GPIO_TypeDef *pGPIOA = (GPIO_TypeDef*)0x40020000; // 假设0x40020000是GPIOA的基地址
pGPIOA->MODER = 0x55;  // 通过指针设置寄存器

9. 代码规范

良好的代码规范提升可读性、可维护性、团队协作效率。

要点:
       1. 命名规范:变量、函数、宏等命名要有意义。例如:变量名用下划线分隔(如button_state),宏全大写(如MAX_VALUE),函数名驼峰或下划线等。
        2.缩进和空格:统一使用空格或制表符(建议空格),缩进一般为4个空格。
        3.注释:对函数、复杂逻辑进行注释,但要避免过多无意义注释。
        3.函数长度:尽量短小,一个函数完成一个功能。
        4.减少全局变量的使用。


对于嵌入式开发,应特别注意:
        1.对寄存器的操作多采用宏定义或结构体指针,使代码清晰。
        2.关键操作(如中断服务函数)应加上必要的注释。

实践建议:

1.结合STM32库或示例代码,观察这些知识点的应用,如stdint.h的使用、位操作(寄存器配置)、结构体(外设寄存器结构)、宏定义(寄存器地址映射)等。

2.尝试编写简单的STM32程序,例如通过位操作控制LED,用结构体指针访问外设寄存器。

希望这些讲解对你有帮助!如果有问题,可以针对某个点进一步探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值