嵌入式C学习笔记

嵌入式C学习笔记,第1张

嵌入式C学习笔记 1.1   2进制、8进制、16进制的相互转换 2进制转换成8进制方法为:

3位二进制数按权展开相加得到1位八进制数。(注意事项,3位二进制转成八进制是从右到左开始转换,不足时补0)。

8进制转换成2进制数:

八进制数通过除2取余法,得到二进制数,每个八进制对应三个二进制,不足时在最左边补充零。

2进制转16进制 :

与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0)。

16进制转2进制 :

十六进制数通过除2取余法,得到二进制数,对每个十六进制为4个二进制,不足时在最左边补零。

8进制转换成16进制 :

与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0

16进制转换成8进制 :

将十六进制转换为二进制,然后再将二进制转换为八进制,小数点位置不变。

1.2   位运算 1.2.1 概括

符号           描述                  运算规则

&                与                 同为1时,结果为1

|                  或                同为0时,结果为0

^                 异或             相同为0,不同为1

<<               左移             二进位全部左移若干位,后面低位补0

>>               右移             二进位全部右移若干位,低位丢失,高位补0

~                 取反             0变1,1变0


1.2.2 或运算符(|)

只有同为0的时候结果才为0

其他情况都为1

只要出现1结果就为1

1.2.3 与运算(&)

运算规则:

都为1的时候结果为1

不同的时候结果为0

都为0的时候也为0

1.2.4 异或运算符(^)

运算规则:

异或运算不管0还是1,只要遇到相同的就为0,只要遇到不相同就为1

1.2.5 取反运算符(~)

运算规则:

                    ~1=0;  
                    ~0=1;
即:对一个二进制数按位取反,即将0变1,1变0。

使一个数的最低位为零,可以表示为:a&~1。

~1的值为1111111111111110,再按“与”运算,最低位一定为0。

因为“~”运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高。

1.2.5 左移运算符(<<)

运算规则:

1、左移可看作 整数M乘以2的N次方
2、"<<"右边的数字就是N,左边的数字就表示这个整数M

 1.2.6 右移运算符(>>)

1、右移可看作 整数M除以2的N次方
2、"<<"右边的数字就是N,左边的数字就表示这个整数M

1.3结构体的使用及参数传递 1.3.1 结构体(struct) 1、基本概念

结构体-----将不同类型的数据成员组织到统一的名字之下,适用于对关系紧密,逻辑相关、具有相同或不同类型的数据进行处理

2、结构体定义格式

struct 结构名(也可称作结构标识符)      

      {

      类型 变量名;

      类型 变量名;

      };

struct 结构名 结构变量;

或者

struct 结构名

       {

       类型 变量名;

       类型 变量名;

       }结构变量;

1.3.2 typedef函数

为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等),

注意typedef与define的区别,typedef 是用来定义一种类型的新别名的,它不同于宏#define,宏是简单的字符串替换

例:

 typedef int INTEGER;

 为int定义了一个新的名字INTEGER,也就是说INTEGER与int是同义词,也可以为结构体定义一个别名

 typedef struct student STUDENT;

或者

typedef struct student
{ 
 int num;
}STUDENT;

上述两条语句是等价的,二者都是为struct student结构体类型定义了一个新的名字STUDENT,即STUDENT与struct student是同义词,所以下列两条语句等价

1.3.3参数传递

参数传递传值方式:将实参的值拷贝给函数或方法,在函数内对形参进行 *** 作, *** 作的对象是实参的拷贝,对实参本身没有影响,在函数结束返回后,形参被丢弃释放,实参的内容不会被改变

参数传递传址方式:将实参的地址传递给函数,在函数内对形参进行 *** 作等同于对实参进行相同的 *** 作,在函数调用结束返回后,形参被释放,实参的内容是对形参进行 *** 作后的结果。

参数传递引用方式:
1.引用实际上是某一个变量的别名,和这个变量具有相同的内存空间;
2. 实参把变量传递给形参引用,相当于形参是实参变量的别名,对形参的修改都是直接修改实参;
3. 在类的成员函数中经常用到类的引用对象作为形参,大大的提高代码的效率。

1.4 静态变量(static)、extern变量,关键字const static

主要用于修饰变量或常量, 使其成为静态变量或常量,延长其生命周期, 可用于修饰局部变量和全局变量。 使用其来修饰的数据类型使其变为静态类型。

在全局变量前加static,全局变量就被定义成为一个全局静态变量(全局变量和静态全局变量的生命周期是一样的,都是在堆中的静态区,在整个工程执行期间内一直存在) 特点如下:

             ①存储区:静态存储区没变(静态存储区在整个程序运行期间都存在);

             ②作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。非静态全局 变量的作用域是整个源程序(多个源文件可以共同使用);

而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。

好处:

不会被其他文件所访问,或者所修改;其他文件中可以使用相同名字的变量,不会发生冲突。

     修饰局部变量

    延长局部变量的生命周期,程序结束才会销毁。

    局部变量只会生成一份内存,只会初始化一次。

    虽然出了声明的作用域,并且其未销毁,但是并无法进行访问。

    存储区域由栈转移到静态存储区。

修饰全局变量

    改变其作用域,只能在当前文件下访问,其他文件不可见。

    其他文件如果声明同名则不会报错,也不会对此全局变量有影响。

修饰函数

       类似修饰变量的作用。

extern用法详解:

1. 声明外部实体

声明外部全局变量或对象,一般用于头文件中,表示在其它编译单元内定义的变量,链接时进行外部链接,如: 
extern int ivalue; 
此时的extern是必须的,省略了extern编译器将视为定义而不是声明,一般地在源代码中定义变量并进行初始化,在头文件中使用extern声明变量。

类似地用于声明外部全局函数,表示该函数在其它编译单元中定义,如: 
extern void func( void ); 
此时的extern可以省略。

2. 声明函数的编译和链接方式

extern 后可以跟"C"或"C++"用于声明全局函数的编译和链接方式,例如: 

extern "C" void add( int a, int b); 
extern "C++" void sum(int* ia, int leng); 
void sum(int* ia, int leng); 

其中的extern "C++"可以省略,它是在C++中默认的链接方式,即后面两种声明方式是等效的。这种声明有两种含义:首先,声明这些函数使用外部链接方式,其实现不在本编译单元之内;另一种含义,则是告诉编译器编译方式,如extern "C"则是告诉编译器使用C语言的编译方式编译该函数。

C++支持函数重载,所以参数不同在编译后生成的函数名也不同,如: 

int max(int a, int b);
int max(float a, float b);

在编译时生成的函数名可能分别为_max_int_int、_max_float_float,通过在函数名后加上参数类型来区分不同的函数,如果使用C语言方式,则生成的函数名中不包含参数信息,只生成_max,所以无法实现重载,也就是说在extern “C”中不能出现函数名重载,例如: 

extern "C" 
{
    int max(int a, int b);
    int max(float a, float b);
}

非法,编译器将报错。而C++标准中并没有定义extern “C”与extern “C++”的具体实现方式,不同编译器生成的符号规则可能不同。

需要注意的是,如果函数声明使用了extern "C",则函数定义必须使用C编译器编译,或者使用extern "C"来修改函数的编译方式,一般地将extern "C"声明的函数的定义所在的源程序扩展名使用.c即可,而C++代码放在.cpp文件中。如果将extern "C"声明的函数实现也放在.cpp中,则需要使用extern "C"来声明函数编译方式,例如: 

 extern "C" 
{
   int max( int a, int b)
   {
     return a > b ? a : b;
   }
 }

只有在C++中使用C语言的库或者两种语言混合编程的时候才会用到extern "C",而在C语言中是不支持extern "C"的,所以为了头文件通用,需要使用宏来控制,例如: 

 1 #ifndef MAX_H 
 2 #define MAX_H 
 3 #ifdef __cplusplus 
 4 extern "C" { 
 5 #endif 
 6 int max (int a, int b); 
 7 #ifdef __cplusplus 
 8 } 
 9 #endif 
10 #endif 

其中__cplusplus为C++定义的宏,凡是C++的编译器都定义了该预编译宏,通过它来检测当前编译器是否使用的是C++编译器。

const
const修饰的量为一个常量即不能被修改的量。但在C语言中的const可以不初始化但后续也就无法对其赋值,所以尽管不初始化不会出错。但要使用const修饰的量就需要对其进行初始化。编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的 *** 作,使得它的效率也很高。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5718472.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存