嵌入式开发学习历程(三)——C语言语法概述

掌握简单C语言的基本语法

基本程序设计思想:
数据类型、运算符、条件分支、循环设计
语句工具的特性:
掌握操作底层,尤其是内存地址的寻址及操作,指针的使用
掌握C语言的设计思路,比普通的语法要重要的多
掌握C语言的核心规律。

要对C语言进行充分学习,推荐以下工具书:
《C专家编程 》
《C程序设计语言》
《程序员面试宝典(第4版)》
《C和指针》

GCC使用以及常用选项
gcc C语言的编译过程:每一阶段调用不同程序来生成可执行程序

  1. 预处理【define、include不是关键字 因为关键字在编译中处理,这两个在预处理中就处理完了】
    【gcc -E】:生成.i文件 将预处理信息宏展开替换到程序源码中
  2. 编译
    【gcc -S】:生成.s编译文件
  3. 汇编
    【gcc -c】:生成.o汇编文件
  4. 链接
    【gcc -o】:生成可执行程序

编译时通常会出现的错误类型以及解决方法:

  1. 预处理错误
    找不到头文件
    【gcc - I】查找头文件的目录

  2. 编译错误
    语法错误,根据提示信息自改

  3. 链接出错
    链接文件不够 比如函数和主函数写在两个C文件上,编译时只编译主函数
    undefine reference to …
    寻找标签是否实现了,在连接时是否加入一起链接
    或者多出 比如两个文件里有重名的函数
    multiple definition of …

预处理的使用:
1. 包含头文件命令:
#include 包含头文件 ——用于调用头文件中的函数
2. 宏:
#define 宏名 宏体
可以使用以下形式
#define ABC (100) 宏定义
#define FUN(x) (1+(x)) 宏函数
值得注意的是宏不进行语法检测,容易出现歧义,在定义宏时应该自己设计。
建议对宏体加括号来保证展开时表达式不存在歧义。

3. 预定义宏:编译器已经定义好的宏名 格式为两下划线 宏名 两下划线 _ _XXXXXX _ _
以下三个宏常用于调试 判断哪些函数执行了 哪些函数没执行 是重要的调试宏
_ _FUCTION _ _:函数名
_ _LINE _ _ :行号
_ _FILE _ _:文件名

4. 条件预处理

#ifdef 
.......
#else 
......
#endif

鉴于程序有调试版本和发行版本之别 为了在发行版本中隐藏结构信息,而不用更改代码,使用条件预处理,例如

#include<stdio.h>
int main ()
{
 #ifdef ABC
printf(“====%s====\n”,__FILE__);
 #endif
     printf(“hello world!\n”);
	 return 0;
}

编译过程中用指令打开:gcc -DABC 等价于 在预处理时在文件添加#define ABC宏定义

宏展开下的#和##的区别:
#:字符串化
展开时在程序中表示一个 ”字符串”
比如:

#define ABC(x)  #x

printf ( ABC( abc\n ) );   //输出结果为abc

##:连接符号
展开时作为前缀后缀来和字符串连接来组成变量,比如:

#define DAY(x) day##x
int day1 = 10;
int day2 = 20;
printf( “the day is %d\n”,DAY( 1 ) ); //输出结果为the day is 10

C语言常用关键字及运算符的操作

重点
掌握C语言的常用关键字以及应用场景,使用技巧
掌握位运算的典型操作
掌握常用的逻辑操作
难点
时候用?怎么去用?为什么要用这个?
熟悉常用运算符的典型操作,总结什么时候使用什么运算符。

关键字:编译器预先定义了一定意义的字符串
包括32个关键字:
auto
break
case char const continue
default do double
else enum extern
float for
goto
if int
long
register return
short signed sizeof static struct switch
typedef
union unsigned
void volatile
while

需要强调的是:
sizeof(不是函数是关键字):
编译器给人查看内存空间容量的工具
return:
函数返回,结束函数

数据类型关键字:限制资源的大小。
C语言操作对象:资源——内存类型和硬件资源。
如何描述资源的属性:资源属性 【大小】
硬件芯片操作的最小单位bit位;软件操作的最小单位byte字节;

要注意每个数据类型所能表示的最大范围。比如char只能表示-127-128,如果赋值char=200,会造成内存溢出,使得得到的值不确定。

  1. char:字符型
    应用场景:
    硬件处理的最小单位,定义空间

  2. int :整形
    编译器最优的处理大小:系统一个周期所能接受的最大处理单位。
    32bit 4B int
    16bit 2B int

  3. long、short:补充int和char之间的空隙

  4. signed:默认类型 ,有符号,最高字节是符号位。多表示数字的表达

  5. unsigned:无符号类型,多用于数据的申请操作时符号位不移动

  6. float(4B)double(8B):表示浮点数,在内存中的表现形式和整形不同
    小数默认用double表示 要用float需要类型转换或者f表示

  7. void:声明标志,不能使用;

自定义数据类型:struct、union、enum、typedef

C编译器默认定义的内存分配不符合实际资源的形式,需要对资源的具体形式进行定义

  1. 结构体struct:元素之间的集合
    语法格式
    声明:struct 结构名{
    \成员变量
    };
    使用:struct 结构名 实例名;

  2. 共用体union:成员变量共用起始地址的内存,是技巧型代码
    语法格式:
    声明:
    union 结构名{
    \成员变量
    };
    使用:union 结构名 实例名;

  3. 枚举enum: 被命名的整形常数的集合
    语法格式:
    声明:enum 枚举名称 {常量列表};
    eg.enum week{
    Monday = 0,Tuesday=1,Wednesday=2,
    Thursday,Friday,Saturday,Sunday
    };
    使用:enum 结构名 实例名;
    枚举内无论枚举多少值,编译器只取一个int值,占用4字节
    多用于对功能进行打包,便于人的理解

  4. typedef :数据类型的别名
    没有出现新的数据形式
    便于程序的阅读。在指针的应用上空间大。多用:xxx_t表示。

逻辑结构关键字:

  1. 选择语句 if、else
  2. 多分支选择语句 switch(整形数字) case default、break
  3. 循环语句 do、while \for
  4. continue 、break、goto(在嵌入式常用到 在同一个函数中跳转是可以的)

类型修饰符:——描述资源属性 存放位置的限定

  1. auto:
    默认情况下使用的关键字——》分配可读可写的区域;
    区域如果在{ },则是存放在栈空间。

  2. register:
    写法:register int a;
    限制变量定义在寄存器上的修饰符。
    定义一些快速访问的变量,然而寄存器值有限,定义的register变量不一定能够存放在寄存器中,如果寄存器不足,a依然存放在存储器中。
    &取地址符号对register变量不起作用,因为寄存器没有地址。

  3. static:静态变量
    应用场景:
    修饰三种数据
    3.1. 函数内部的变量
    int fun()
    {
    static int a;
    }
    3.2. 函数外部的变量 全局变量
    static int a
    3.3. 函数名的修饰
    static fun();

  4. extern:外部声明
    应用场景:全局变量的声明

  5. const:
    对常量的定义、效果弱(把变量设为只读,然后有办法改变变量的值、存在内存泄漏问题)

  6. volatile:
    提示编译器编译方法的关键字,不优化编译。

运算符:

  1. 算数操作运算:+、- 、*、/、%
    *乘法:CPU不支持乘法,可能使用多个周期,甚至软件函数模拟方法实现
    % 取模:常用于去一个范围数,得到M进制的数,求循环数据结构的下标
  2. 逻辑运算:返回结果为1、0
    A || B、A&&B 存在逻辑短路,前一个表达式判定的对错影响后一个表达式的判定
    表达式关系不能交换

!:逻辑非
‘>’、>=、<、<=:比较符
(?:) :判断逻辑

  1. 位运算:

<<左移:表示二进制下的乘法,符号位不改变
'>>'右移:表示二进制下的除法,对于有符号型,右移不移动符号位
&与、|或:任意一位与0等于零,用于对位清零。任意一位或1等于1,用于置位。
^异或 常用算法:不引入新的变量,交换两数:使用异或性质
a=a^b;
b=a^b;
a=a^b;
~非:取反

  1. 赋值运算:

=等号:对变量进行更新(+=,-=,&=…….)

  1. 内存访问符号:

():限制符(a+b)*c、函数访问fun()
[ ]:数组限制符,内存访问的ID符号
{ }:函数体限制符
->地址方位(*p->next)
.变量访问 (student.name)
&取地址:&p
*指针:*p;

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值