19.9.21 嵌入式C语言学习

准备再深入学习C语言为了更好的了解嵌入式编程 ,为后续的深入学习打下基础,目前就自己感觉而言Linux的学习不是走一条线,而是多线并进。
C语言的学习的是必须掌握的,经常做题已经对里面编程语法的熟悉
Linux是操作系统的学习,了解其内部的运行原理,内核,以及一些命令的使用
要一直走在学习的路上才能发现自己走的路对不对,才能及时调整,如果不走这条路永远只能停在原地,连错误的机会都没有。

1.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define 宏名 宏体
宏名:大写字母表示
#define SECOND_OF_YEAR 123456
#define SECOND_OF_YEAR (365243600)

que1:会考虑到一种是直接把值算出来就赋值给宏名,防止每次调用CPU都去对这个算式进行运算,但是这种担心是多余的。
上面第一种是数值常量,第二钟是常量表达式。在编译过程中直接就把值算出来,并赋值给宏体

tip:宏体上都要加括号

为了防止宏体数值过大,后面加上限制符:
#define SECOND_OF_YEAR (365243600)UL L:unsigned long,代表无符号长整形,限制为4个字节,而且对于本题秒数为整数,还必须是无符号形的
8bit: 0-255 256个数
16bit: 0-65535 655356个数

宏体的实现
(1)365243600
(2)直接求出该数值

数据声明问题
2.用变量a给出下面的定义

a)一个整型数
int a;
b)一个指向整型数的指针
int *a
看到要定义指针的 *a
在看是什么型式的
c)一个指向指针的指针,它指向的指针是指向一个整形数
int **a;
int * *a; 左边的 修饰右边的a
d)一个有10个整型数的数组

 int  a[10];
  cpu在识别时,看到右边的方框,就是数组标签。在看内部的数字告诉分配多少个数组空间
  cpu识别时,右边的优先级高于左边,先看右边有无方框,识别为是否是数组,在看左边的星号,看是否是指针*
 

e)一个有10个指针的数组,该指针是指向一个整型数的
int *a[10];

同样先看右边,是[],所以确定a的数组标签,在看左边*,则为一个存指针的数组

f)一个指向有10个整型数数组的指针

int (*a)[10];
int [10] *a  //a是指针必须要是个*
然后才是[10]代表有10个这样的数组
所以就要对其先进行限定,int (*a)[10];
括号内,先限定其为指针,然后在看方框,知道这个指针是指向数组的。

g)一个指向函数的指针,该函数有一个整形参数并返回一个整型数

int (*main)(int a)
如果写成 int *main(int a)  那么根据函数识别优先级的判定,先判断了右边的园括弧
则先定义其为函数,而再看左边的*号时候,就是返回值了.
 则 int *main(int a)  代表的是一个返回值为整形指针的函数,而不是一个指向函数返回值为整形值的指针。

h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整型数

int (*a[10])(int)

这里可以看出对于,一个函数的整型参数可以不用给出名字,给出整型符号也是可以的。

修饰符
对内存资源存放位置的限定
资源属性中位置的限定

关键字static的作用是什么? static:静态
1.修饰局部变量
默认局部变量 在 栈空间内存在,函数一返回,栈空间就被释放了,生存期短。
局部静态化,局部变量 在 静态数据段保存,生存期变长。
2.修饰全局变量
对于全局变量来说,放置的位置不会有变化都在静态数据段中保存
作用是防止重命名

3.修饰全局函数
作用是防止重命名
防止不同文件访问时,有相同名字时造成的问题

比如有3个.c文件,一个是  主函数的,另外两个是功能函数
两个函数都定义全局变量  int a;
则如果主要函数调用时候就会出现问题,
所以加上static后,则该变量只在本文件内有效,不能被其他文件调用

在多文件程序中有用,多人合作写文件时,非常有用

全局和局部的概念:
在一个文件内,在 {} 外部的就为全局,内部的就是局部

int fun()
{
}
int main()
{
fun();
}
fun()来说就是全局

关键字const有什么含意
C:只读,建议性, 不具备强制性 不等于一个常量
通过越界等一些方法,可以更改他的值

关键字volatile的含意?据三个例子
防止C语言编译器的优化。
他修饰的变量,该变量的修改 可能通过第三方来修改
当引入线程,中断概念时,就会涉及到第三方

位操作
嵌入式系统总是要对用户对变量或寄存器进行位操作。给定一个整形变量a,写两段代码,第一个设置a的bit3,第二个清楚a的bit3。以上两个操作中,保持其他位不变

一般意义上,设置(select)就是置1
清除(clear)就是置0

unsgined  int a;  //这里的的a代表的不是数学意义,而是电路板上的物理意义,所以要使用无符号整形
a |= (1<<3);    //bit3  是第四位,这里要注意

a&=~(1<<3);

访问固定内存位置

在某工程中,要求设置一绝对地址0x67a9的整形变量的值位0xaa66。编译器是一个纯粹的ANSI编译器,写代码去完成这一任务

第一钟
int *p =(int *)0x67a9;/  代表的是绝对地址的拷贝   (int *)0x67a9   强制把67a9转换为地址
p[0] = 0xaa66; //p[0]就是0x67a9内部放的值
第二种
*((int *)0x67a9)=0xaa66;
(int*)0x67a9  这一步是强转0x67a9为地址,不然CPU只能识别它为一个数字
*(int*)0x67a9 )  这一步是取内容,直接对0x67a9这个内容进行更改,简洁

???
((void(*)(void))0x67a9)();
转换为函数的



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值