首页技术文章正文

嵌入式C++开发详解【黑马C++培训】

更新时间:2023年01月03日 14时21分08秒 来源:黑马程序员论坛

黑马中级程序员课程

嵌入式C++开发详解(一)

一、C++概述

1.嵌入式开发中为什么选择C++语言?

(1)面向过程编程的特点

  C语言特点:C语言是在实践的过程中逐步完善的

             ·没有深思熟虑的设计过程

               ·使用时存在很多“灰色地带”

                ……

             ·残留量过多低级语言的特征

               ·直接利用指针进行内存操作

                ……

  面向过程的编程特点:

             面向过程程序设计:数据结构+算法

  ·主要解决科学计算问题,用户需求简单固定

  ·特点:分析解决问题所需要的步骤

          利用函数实现各个步骤

          依次调用函数解决问题

  ·问题:软件可重用性差

          软件可维护性差

          构建的软件无法满足用户需求

(2)面向对象编程的特点

  面向对象的编程特点:

            面向对象程序设计:由现实世界建立软件模型

   ·将现实世界中的事物直接映射到程序中,可直接满足用户需求

   ·特点:直接分析用户需求中涉及的各个实体

           在代码中描述现实世界中的实体

           在代码中关联各个实体协同工作解决问题

   ·优势:构建的软件能够适应用户需求的不断变化

           直接利用面向过程方法的优势而避开其劣势

  C++语言特点:高效的面向对象语言,并且能够兼容已经存在的代码

2.C++为什么难学?

C++支持的编程格式:

·过程式

·数据抽象

·基于对象

·面向对象式

·函数式

·泛型形式

·模板元形式

值语义和对象语义:

值语义可以拷贝与赋值,对象语义不可进行拷贝与赋值

3.C++相关基础知识点

(1)C++之父是谁?

    本贾尼·斯特劳斯特卢普

1982年,美国AT&T公司贝尔实验室的Bjarne Stroustrup博士在c语言的基础上引入并扩充 了面向对象的概念,发明了—种新的程序语言。为了表达该语言与c语言的渊源关系,它被命名为C++。而Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)博士被尊称为C++语言之父。

(2)C++语言的标准

  C++ 98 标准

  C++标准第一版,1998年发布。正式名称为ISO/IEC 14882:1998[17]  。

  C++ 03 标准

  C++标准第二版,2003年发布。正式名称为ISO/IEC 14882:2003[18]  。

  C++ 11 标准

  C++标准第三版,2011年8月12日发布。正式名称为ISO/IEC 14882:2011[19]  。

  C++11对容器类的方法做了三项主要修改。

  首先,新增的右值引用使得能够给容器提供移动语义。其次,由于新增了模板类initilizer_list,  

  因此新增了将initilizer_list作为参数的构造函数和赋值运算符。第三,新增的可变参数模板(variadic template)和函数参数包(parameter pack)使得可以提供就地创建(emplacement)方法。

  C++ 14 标准

  C++标准第四版,2014年8月18日发布。正式名称为ISO/IEC 14882:2014[21]  。

  C++14是C++11的增量更新,主要是支持普通函数的返回类型推演,泛型 lambda,扩

  展的 lambda 捕获,对 constexpr 函数限制的修订,constexpr变量模板化等[22]  。

(3)C++11值得学习的新特性

·智能指针如shared_ptr、weak_ptr等

·rvalue reference

·function/bind

·lambda expression and closure

二、从C到C++的升级

1.声明定义

C++:C++中更强调语言的实用性,所有变量都可以在需要使用时再定义

     如:for(int i = 0; i < 2; i++)

C语言:变量必须在作用域开始时定义

2.register关键字的升级

   经常被访问的变量我们就可以用register修饰为寄存器变量,请求编译器尽可能的将变量存在CPU的内部寄存器中,节省了CPU从内存中抓取数据的时间,从而提高了运行效率。

C语言:register只能修饰局部变量,不能修饰全局变量和函数;

         register修饰的变量不能通过取地址来获取寄存器变量;

         register修饰的变量一定是CPU能接受的数据类型。

C++:在C++中依然支持register关键字

      C++编译器有自己的优化方式,不使用register中也可能做优化

      C++中可以取register变量的地址(C++编译器发现程序中需要取register

      变量的地址时,register对变量声明无效)

3.const关键字

C++:C++编译器对const常量的处理

     ·当碰见常量声明时在符号表中放入常量

     ·编译过程中若发现使用常量则以符号表中的值替换

     ·编译过程中若发现对const使用了extern或者&操作符,则给对应的常量

       分配存储空间

  注意:C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中

        的值。

C语言:C语言中const修饰变量,空间里的值可变,但是不能通过变量名来修改这个空间的对应值。

4.内存分配与释放

(1)C++中动态内存分配

·C++中通过new关键字进行动态内存申请

·C++的动态内存申请是基于类型进行的

·delete关键字用于内存释放

变量申清:

Type *pointer = new Type;

……

delete pointer;

数组申清:

Type *pointer = new Type[];

……

delete[] pointer;

(2)new与malloc区别

·new关键字是C++的一部分,malloc是由C库提供的函数

·new以具体类型为单位进行内存分配,malloc只能以字节为单位进行内存

  分配

·new在申请单个类型变量时可进行初始化,malloc不具备内存初始化的特

  性

5.引用VS指针

(1)引用

     ·引用是给一个变量起别名

     ·定义一个引用的一般格式:

          ·类型 &引用名 = 变量名

          ·例如:int a = 1;

                  int &b = a; //b是a的别名,因此a和b是同一个单元

      注意:定义引用时一定要初始化,指明该引用变量是谁的别名

     ·在实际应用中,引用一般用作参数传递与返回值

(2)const引用是指向const对象的引用

(3)函数传参:按引用传递

引用传递方式是在函数定义时在形参前面加上运算符“&”

例如:void swap(int &a,int &b);

·按值传递方式容易理解,但形参值得改变不能对实参产生影响

·地址传递方式通过形参的改变使响应的实参改变,但程序容易产生错误且难以阅读

·引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数调用显得方便、自然。

(4)函数返回值:引用作为函数返回值

·引用的另一个作用是用于返回引用的函数

·函数返回引用的一个主要目的是可以将函数放在赋值运算符的左边

·注意:不能返回对局部变量的引用

(5)引用与指针的区别

·引用访问一个变量是直接访问,而指针是间接访问

·引用是一个变量的别名,本身不单独分配自己的内存空间,而指针有自己的内存空间

·引用一经初始化不能再引用其它变量,而指针可以

·尽可能使用引用,不得已时使用指针

6.函数升级

(1)内联函数(inline):以空间换时间(频繁调用且简短)

      内联函数的使用:

          inline int max(int a,int b)

          {

               return a>b?a:b;

          }

          #define MAX(a,b) (a)>(b)?(a):(b)

      内联函数与带参数宏的区别:

     ·内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实

       参表达式进行求值,然后传递给形参;而宏调用只用实参简单地替换形

       参。

     ·内联函数是在编译的时候、在调用的时候将代码展开的,而宏则是在预

       处理时进行替换的

     ·在C++中建议有用inline函数来替换带参数的宏

(2)函数重载(overload)

    相同的作用域,如果两个函数名称相同,而参数不同,我们把它们称为重载overload

函数重载的条件:(函数的返回值不能作为条件)

  ·函数重载不同形式:

        ·形参数量不同

        ·形参类型不同

        ·形参顺序不同

        ·形参数量和形参类型都不同

  ·调用重载函数时,编译器通过检查参数的个数、类型和顺序来确定相应

    的被调用函数

     name managling与extern “C”:

     ·name managling 这里把它翻译为名字改编

     ·C++为了支持重载,需要进行name managling

     ·extern“C”实现了C与C++混合编程

           #ifdef__cpluscplus

           extern“C”

           {

                #endif

                 ……

                #ifdef__cpluscplus

           }

           #endif

(3)带默认参数的函数:

     ·函数没有声明时,在函数定义中指定形参的默认值

     ·函数既有定义又有声明时,声明时指定后,定义后就不能再指定默认值

     ·默认值的定义必须遵守从右到左的顺序,如果某个形参没有默认值,则

       它左边的参数就不能有默认值

       void funcl(int a,double b = 4.5,int c = 3)   //合法

       void funcl(int a = 1,double b ,int c = 3)   //不合法

     ·函数调用时,实参与形参按从左到右的顺序进行匹配

7.命名空间-namespace

(1)命名空间

    ·在C语言中只有一个全局作用域

     ·C语言中所有的全局标识符共享一个作用域

         ·标识符之间可能有冲突

·C++中提出了命名空间的概念

     ·命名空间将全局作用域分成不同的部分

     ·不同命名空间中的标识符可以同名而不会发生冲突

     ·命名空间可以相互嵌套

     ·全局作用域也叫默认命名空间

(2)如何定义命名空间

namespace First

{

     int i = 0;

}

namespace Second

{

int i = 1;

}

using namespace First;

int main()

{

cout<<i<<endl;

cout<<Second::i<<endl;

return 0;

}

(3)如何使用命名空间

·使用整个命名空间:using namespace name;

·使用命名空间中的变量:using name::variable;

·使用默认命名空间中的变量:  ::variable

默认情况下可以直接使用

默认命名空间中的所有标识符

8.新的类型转换运算符

(1)static_cast<T>(expr)

·用于基本类型间的转换,但不能用于基本类型指针间的转换

·用于有继承关系类对象之间的转换和类指针之间的转换

int main()

{

int i = 0;

char c = ‘c’;

int *pi = &i;

char *pc = &c;

c = static_cast<char>(i);//success

pc = static_cast<char *>(pi);//error

    return 0;

}

static_cast是在编译期进行转换的,无法在运行时检测类型,所以类类型之间的转换可能存在风险

(2)const_cast<T>(expr)

const_cast强制类型转换——用于去除变量的const属性

int main()

{

    const int &j = 1;

    int & k = const_cast<int&>(j);

    const int x = 2;

        int & y = const_cast<int&>(x);

        k = 5;

        cout << j << endl;

        cout << k << endl;

        y = 3;

        cout <<x<<endl;

        cout<<y<<endl;

        cout <<&x<<endl;

        cout<<&y<<endl;

        return 0;

}

(3)reinterpret_cast<T>(expr)  

  reinterpret_cast强制类型转换

·用于指针类型间的强制转换

·用于整数和指针类型间的强制转换

typedef void(pf)(int)

int main()

{

int i = 0;

char c = ‘c’;

int * pi = reinterpret_cast<int *>(&c);

char * pc = reinterpret_cast<char *>(&i);

PF * pf = reinterpret_cast<PF*>(0x12345678);

c = reinterpret_cast<char>(i);

return 0;

}

reinterpret_cast直接从二进制位进行赋值,是一种极其不安全的转换。

(4)dynamic_cast<T>(expr)

   dynamic_cast强制类型转换

·主要用于类层次间的转换,还可以用于类之间的交叉转移

·dynamic_cast还具有类型检查的功能,比static_cast更安全

推荐了解热门学科

java培训Python人工智能Web前端培训PHP培训
区块链培训影视制作培训C++培训产品经理培训
UI设计培训新媒体培训产品经理培训Linux运维
大数据培训智能机器人软件开发




传智播客是一家致力于培养高素质软件开发人才的科技公司“黑马程序员”是传智播客旗下高端IT教育品牌。自“黑马程序员”成立以来,教学研发团队一直致力于打造精品课程资源,不断在产、学、研3个层面创新自己的执教理念与教学方针,并集中“黑马程序员”的优势力量,针对性地出版了计算机系列教材50多册,制作教学视频数+套,发表各类技术文章数百篇。

传智播客从未停止思考

传智播客副总裁毕向东在2019IT培训行业变革大会提到,“传智播客意识到企业的用人需求已经从初级程序员升级到中高级程序员,具备多领域、多行业项目经验的人才成为企业用人的首选。”

中级程序员和初级程序员的差别在哪里?
项目经验。毕向东表示,“中级程序员和初级程序员最大的差别在于中级程序员比初级程序员多了三四年的工作经验,从而多出了更多的项目经验。“为此,传智播客研究院引进曾在知名IT企业如阿里、IBM就职的高级技术专家,集中研发面向中高级程序员的课程,用以满足企业用人需求,尽快补全IT行业所需的人才缺口。

何为中高级程序员课程?

传智播客进行了定义。中高级程序员课程,是在当前主流的初级程序员课程的基础上,增加多领域多行业的含金量项目,从技术的广度和深度上进行拓展“我们希望用5年的时间,打造上百个高含金量的项目,覆盖主流的32个行业。”传智播客课程研发总监于洋表示。




黑马程序员热门视频教程

Python入门教程完整版(懂中文就能学会)零起点打开Java世界的大门
C++| 匠心之作 从0到1入门学编程PHP|零基础入门开发者编程核心技术
Web前端入门教程_Web前端html+css+JavaScript软件测试入门到精通


分享到:
在线咨询 我要报名
和我们在线交谈!