嵌入式高级C笔记01——关键字和运算符
1. 简单数据类型的位长
大小端(endian)
大小端是CPU存放数据的两种不同顺序。对于整型和长整型等数据类型:大端认为在低地址上存放的是这个整数的高位字节,在高地址上存放的是这个整数的低位字节。小端恰好相反。一般来说X86系列CPU为小端的字节序,PowerPC,68K系列则是大端,ARM系列处理器内部是小端,但是可以被配置为访问大端的存储器。可以用以下代码来测试处理器的大小端:
typedef unsigned char BYTE;
int main(){
unsigned int num,*p;
p = #
num = 0;
*(BYTE *)p = 0xff;
if(num == oxff)
printf("this cpu is little endian!\n");
else
//num == 0xff000000
printf("this cpu is big endian!\n");
return 0;
}
2. unsigned与signed
大多数编译器都约定char是一个有符号数,ARM的编译器再默认情况下认为char是个无符号数。
3. 存储类型关键字
1) auto关键字
默认情况下局部变量的存储类型是自动的,也就是这个变量要么被存储在堆栈中,要么被存储在CPU内部的寄存器中。
2) register关键字
关键字register可以用于自动变量的声明。这个关键字提示编译器将register关键字修饰的自动变量存储在CPU内部的通用寄存器中而不是存储器中。
需要注意的是如果一个自动变量被编译器分配到了CPU内部的寄存器,对这个变量使用&来取地址是毫无意义的,因为许多机器并不为寄存器进行统一编制。下面代码在ARM编译器中可能会造成data Abort
int *test(int *ptr){
int a;
if(ptr!=NULL)
{
a = *ptr;
return &a; //如果编译器将其分配进CPU的寄存器,则这个取地址是无效的
}
return NULL;
}
3) static关键字
static关键字有三种不同的用途
a. 如果它用于函数内部的局部变量声明,static关键字的作用是改变局部变量的存储类型,从自动变量变成静态变量,这个变量将在编译的时候由编译器分配一个静态的地址空间而非堆栈。
b. 用于函数定义,则类似Java的private
c. 用于全局变量定义,也类似Java的private
4) extern关键字
extern关键字主要有两种使用方法:
a. 在C文件中直接声明某个其他文件中定义的函数或全局变量为extern,从而告诉编译器这个函数或变量是在其他C文件中。
b. 在头文件中声明某个函数或变量为extern然后在需要引用该函数或变量的C文件中包含这个头文件。
以下为例子:
共有2个C文件,分别为file1.c和file2.c在file2.c中定义了函数int fun(int )和全局数组int a[100];在file1.c中的函数main需要调用fun函数和全局数组a。采用第一种方法解决:
/*以下为file1.c*/
extern int a[];
extern int fun(int);
int array[100];
void main(){
int i;
for(i = 0;i<100;i++){
a[i] = i;
array[i] = fun(a[i]);
}
return;
}
/*以下为file2.c*/
int a[100];
int fun(int b){
return b*(b-1);
}
第二种方法(推荐):
/*以下为file1.c*/
#include "file2.h"
int array[100];
void main(){
int i;
for(i = 0;i<100;i++){
a[i] = i;
array[i] = fun(a[i]);
}
return;
}
/*以下为file2.c*/
#include "file2.h"
int a[100];
int fun(int b){
return b*(b-1);
}
/*以下为file2.h*/
#ifndef _FILE2_H
#define _FILE2_H
extern int a[];
extern int fun(int);
#endif
4. const关键字
利用const关键字声明一个变量是“只读”的,在C语言中这意味着这个变量的值不能改变。注意将只读和常量的概念区分开来。
int const a = 20;
//下面这个声明是错误的,因为a是变量,在编译时候a的值是不确定的
int array[a];
还应该强调的是指针常量和常量指针。
除此之外虽然const关键字没有在本质上改变变量的属性,但是const还是意义非凡的:
首先,const的作用是给读代码的人传达非常有用的信息,然后,通过给编译器的优化器一些附加的信息,使用const也许能产生更紧凑的代码。
5. volatile关键字
一个定义为volatile的变量表示该变量可能会意想不到的被改变。下面是volatile变量的几个例子:
并行设备的硬件寄存器
一个中断服务子程序中会访问到的非自动变量
多线程应用中被几个任务共享的变量。
6. 隐式类型转换
这儿有个著名的陷阱:
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b>6)?printf(">6\n"):printf("<=6\n");
}
上面代码的结果是”>6”,因为编译器会将有符号整数转换成无符号整数。
另一个例子:
int a =5000;
int b = 50;
long c =a*b;
这里a*b后把值赋给c可能a*b后超出int范围,最后出现错误。
应该为long c = (long) a*b;
7. 运算符词法分析
首先一个问题:
c = a+++b; 这个是什么意思
在C语言编辑器中有“Token”这样的概念,C语言的某些Token(比如/,*,=等)只有一个字符长,称为单Token。而C语言中其他一些Token以及关键字,函数名,数组名,变量名包含了多个字符,成为多字符Token。C语言在解决问题是有一个原则:每一个Token应该包含尽可能多的字符。
那么上面的表达式意思就是:
c = (a++)+b
分享到:
相关推荐
ARM汇编语言与嵌入式C语言混合编程————内嵌汇编[归纳].pdf
嵌入式C语言不可不用的关键字 嵌入式C语言不可不用的关键字 嵌入式C语言不可不用的关键字 嵌入式C语言不可不用的关键字
C语言进阶——嵌入式系统高级C语言编程(东大 凌明)
C语言进阶——嵌入式系统高级C语言编程 C语言进阶-第一讲概述 C语言进阶-第二讲C语言复习 C语言进阶-第三讲编译汇编调试 C语言进阶-第四讲存储器与指针 ......
《嵌入式系统高级C语言编程》是2011年北京航空航天大学出版社出版的图书,作者是凌明。本书以实际项目中的代码为例来进行介绍,详细分析在嵌入式系统开发中程序员应该注意的方法、技巧和存在的陷阱。
C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程)
《嵌入式Linux C语言应用程序设计》读书笔记《嵌入式Linux C语言应用程序设计》读书笔记《嵌入式Linux C语言应用程序设计》读书笔记《嵌入式Linux C语言应用程序设计》读书笔记《嵌入式Linux C语言应用程序设计》...
1.1嵌入式系统的定义和特点3 1.1.1嵌入式系统的定义3 1.1.2嵌入式系统和通用计算机比较4 1.1.3嵌入式系统的特点5 1.2嵌入式系统的硬件6 1.2.1嵌入式处理器7 1.2.2嵌入式存储器15 1.2.3嵌入式I/O设备18 ...
c语言进阶——嵌入式高级C语言编程 东南大学国家专用集成电路系统工程技术研究中心
嵌入式系统高级C语言编程,深入理解C语言指针的奥秘。两篇PDF讲义
C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程) C语言进阶(嵌入式高级C语言编程)
嵌入式Linux之我行——内核通知链机制的原理及实现.pdf嵌入式Linux之我行——内核通知链机制的原理及实现.pdf
嵌入式系统词汇表 词汇表 嵌入式 嵌入式系统
嵌入式系统课程设计汇本——贪吃蛇.doc
·嵌入式Linux之我行——PWM在ARM Linux中的原理和蜂鸣器驱动实例开发 ·嵌入式Linux之我行——S3C2440上RTC时钟驱动开发实例讲解 ·嵌入式Linux之我行——S3C2440上看门狗(Watchdog)驱动开发实例讲解 ·嵌入式Linux...
嵌入式,c语言常用关键字;华清软件;武汉大学
针对嵌入式的C语言学习——内存处理
《ARM嵌入式技术原理与应用——基于XScale处理器及VxWorks操作系统 [单片机与嵌入式系统 ┈→ 嵌入式系统教程]》可作为高等院校计算机、电子、电信等专业的师生进行嵌入式系统教学的理论和实践教材。
C语言进阶(嵌入式系统高级C语言编程) C语言进阶(嵌入式系统高级C语言编程) C语言进阶(嵌入式系统高级C语言编程)
嵌入式软件编程之深入理解关键字