栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

从C语言到C++,必须知道的一些内容

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从C语言到C++,必须知道的一些内容

C++
  • 从C到C++

C++基本情况介绍

​ ++ C语言运算符 C++是在C语言之上的扩展

​ 起初的名称:C with Class 即带类的C语言,只是C语言的一部分

  1. C++的诞生时间

    C++ 是由 Bjarne Stroustrup(本贾尼·斯特劳斯特鲁普 ) 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言,最初命名为带类的C(C with Class),后来在 1983 年更名为 C++。

    C++的标准化工作于1989年开始。

    1998年,C++的ANSI/IS0标准被投入使用。

    时间标准版本
    1989/199889年制定98年投入使用
    2003第二个C++标注,对98标准略作修改
    2011第三个C++标准,颠覆性的标准
    2014每三年提出一个标注

    C++ 是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序。

  2. C++的特点

    • C++宏观上面向对象,微观上也面向过程,C语言为面向过程的语言
    • 支持运算符重载(令自定义的类型也支持运算符(算数运算符,逻辑运算符等)
    • 支持异常机制——错误处理(errno) #include
    • 支持泛型编程——对类型抽象化
  3. C++的应用

    • 兼顾执行效率和开发效率
      • C语言具有其他高级语言无法比拟的高效率
      • C++有优化编译器,在部分场合能让C++具有C的执行效率
      • 面向对象有丰富的扩展库
    • 科学计算库 (基本上由C++实现
    • 计算机网络 (ACE库
    • 广泛引用与网络编程
    • 网络游戏 (LOL等大型网络游戏)
    • 强建模能力 (数字建模 3D
    • 桌面应用程序 (office, windows桌面
    • 驱动程序 (C++优化编译器使得其执行效率提高
  4. C和C++的区别

    • C++基本完全兼容C语言
    • C语言面向过程,C++面向对象(宏观上面向对象,微观上也面向过程)
    • 其他可见C++特点
    • C++的函数支持重载、默认值、哑元
    • C++的枚举是一种强类型
  5. 第一个C++程序!

    #include//C++标准IO库,一般C++的库基本没有.h后缀
    //C++中可以直接使用C 语言的头文件,但是如果使用C语言标准的头文件,一般来说C++也有自己提供的 #include  #include
    using namespace std;//C++ 把标准库中的对象类型的名称放在了std中。
    int main()
    {
    	cout<<"HelloWorld!"< 

    使用g++编译器 在文件名称后加 -lstdc++也可以用gcc编译器

    后缀名一般为cpp 写成C,c++,cc也行

  • 独特的基本数据类型

    • C++中有bool布尔类型
      • bool类型的取值为 true 和 false 表示 真和假 底层用 1和0存储
    • 在输出时,true – 1 false—0 可以使用boolalpha 输出 true 和 false
  • C++的struct类型

    与C语言中struct的区别:

    1. C++定义完结构体变量后,定义变量可以不使用struct关键字

    2. C语言sizeof(空结构体)的大小为0,C++中为1,主要是为了标识内存

    3. C++的struct中可以定义函数(在自定义类型中定义函数,即面向对象的思想)

      在其中定义的函数可以直接访问结构体中的变量

      结构体中的变量可以用static修饰,但需要在结构体外进行定义

      类型 结构体名::成员名 = init_val;

      C++的结构体可以用访问控制属性,(public、protected、private)

      允许继承

  • C++的enum

    是一种独立的类型,不能和C语言一样直接用数字赋值枚举类型的变量,只能用枚举值

    但是可以用枚举给int类型变量赋值

    enum Direction{UP,DOWN,LEFT,RIGHT};
    
    Direction d = UP;//cout << d << endl; 依然是整数 
    d = DOWN;
    d = LEFT;
    d = RIGHT;
    
    d = 0;   d = 1;   d = 1024;          //错误的  但是C语言中允许 
    int num = d;
    num = LEFT;  //可以的
    
  • C++的union

    • C++中支持匿名联合(既没有类型,也没有定义联合变量)
    • C++中的匿名联合表示的是变量在内存中的布局方式
    • 可以直接访问匿名联合中的属性
    //以编译时,以联合的形式编译布局a,b,c,即让a,b,c共用一块内存
    union{
        int a;
        int b;
        char c;
    };
    
    a = 1024;
    b = 9527;
    c = 'A';
    
  • C++的string

    //保留了C风格的字符串,同时引入了string类型的字符串
    string s1;  //空字符串
    string s2 = "Hello world"; //C指针的初始化方式
    string s3("Hello world");
    string s4 = {"HEllo world"};
    string s5 = s4;
    string s6(10,'X'); //"XXXXXXXXXX"
    //指针是一种天然的迭代器
    string s7(iterator begin,iterator end);  //[begin,end)  用这个区间中的字符构造字符串
    

string变量的赋值

string s = "Hello world";
s = "中国速度";  //对string变量进行赋值

string s1("hello");
s1 = s;        //字符串之间进行赋值

  • 字符串的拼接 +

  • 字符串中字符的访问与修改 []

  • 字符串长度

    size_t length();                s.length()
    
  • 返回C风格的字符串

    char *c_str();
    
  • 字符串判断相等 ==

    string a("Hello"),b("Hello");
    if(a == b){//字符串a和字符串b相等
        
    }
    
  • 元素访问

    string s("Hello world");
    //1.下标  []
    cout << s[0] << endl;
    s[1] = 'E';
    //2.at  对比[]  进行越界检查    如果越界会抛出异常   一旦越界,会抛出 std::out_of_range 异常
    char& at(size_t index);
    cout << s.at(0) << endl;   //s[0]
    //3.front  C++11  g++ -std=c++0x
    char& front()   获取首字符  返回其引用
    //4.back   
    char& back()    获取末尾字符          不是
    //5.data()
    const char* data();
    //6.c_str()
    const char *c_str();
    
  • 迭代器(指针)

    正向迭代器    string::iterator it
    iterator begin();            //正向迭代器   字符串首字符的地址
    iterator end();              //正向迭代器   字符串最后一个字符的下一个地址
    
    逆向迭代器
    reverse_iterator rbegin()    //逆向迭代器   字符串最后一个字符的地址
    reverse_iterator rend()      //逆向迭代器   字符串第一个字符的前一个地址
        
    //不能通过迭代器修改字符串中的内容
    常正向迭代器   const_iterator  
        cbegin()    cend()
    常逆向迭代器   const_reverse_iterator 
        crbegin()   crend()
        
        
    正向迭代器   ++    往后偏移    --  往前偏移
    逆向迭代器   ++    往前偏移    --  往后偏移
        
    *迭代器             就相当于指针解引用
    
    • 字符数量和容量

      bool empty()              //检查字符串是否为空
      size_t size();            //字符数量
      size_t lenght();          //字符数量
      void reserve(size_t s);           //预分配内存   如果s小于目前的容量则不会干任何事件  只扩不缩
      size_t capacity()         //容量    自动扩容 
      ~~~
      
      
    • 操作

      void clear();
      //指定位置
      basic_string& insert( size_type index, size_type count, CharT ch );//在index位置插入count个ch字符
      basic_string& insert( size_type index, const CharT* s ); //在index位置插入一个C风格的字符串
      basic_string& insert( size_type index, const basic_string& str, size_type index_str, size_type count );//在index位置插入 str字符串 index_str开始往后count个字符
      
      //指定迭代器
      iterator insert( iterator pos, CharT ch );
      void insert( iterator pos, size_type count, CharT ch );
      void insert( iterator pos, InputIt first, InputIt last );
      
      
      basic_string& erase( size_type index = 0, size_type count = npos );//从index处开始移除,移除count个字符,如果没有传递count,则移除至末尾
      
      iterator erase( iterator position ); //移除指定位置(迭代器)的元素
      iterator erase( iterator first, iterator last );//移除[first,last)区间的元素
      
      void push_back( CharT ch );  //自动扩容 
      void pop_back();
      
      //追加若干个字符
      basic_string& append( size_type count, CharT ch );
      basic_string& append( const basic_string& str );//追加一个字符串
      basic_string& append( const basic_string& str,size_type pos, size_type count = npos );
      
      
      int compare( const basic_string& str ) const;
      支持==
          
      basic_string& replace( size_type pos, size_type count,const basic_string& str );
      
      basic_string substr( size_type pos = 0, size_type count = npos ) const;
      constexpr basic_string substr( size_type pos = 0, size_type count = npos ) const;
      
      //如果没有找到str  则返回 npos     从pos位置开始查找
      size_type find( const basic_string& str, size_type pos = 0 ) const;
      
    名字空间
    • 名字空间其实是对代码的逻辑划分,避免名字冲突

    • 名字空间的定义

      namespace 名字空间名{
          定义全局变量;
          定义函数;
          定义类型;
      }
      
    • 使用名字空间中的内容 作用域限定符 ::

      名字空间::标识符                     ---指定使用哪个名字空间中的内容
      
    • 声明名字空间对当前作用域可见

      using namespace 名字空间名;
      
      直接使用标识符           不需要  名字空间::标识符
      
      • 如果使用using namespace声明多个名字空间,如果使用同名的标识符,会引发冲突,引发冲突之后,必须使用 名字空间::标识符
    • 把名字空间中的标识符导入到当前作用域

      using namespace::标识符               优先级会比using namespace 名字空间   优先级高  局部优先原则
      
    • 名字空间名相同的名字空间 自动合并

      • 名字空间名不会有重定义的问题
      namespace N1{
          int a;
      }
      namespace N1{
          int b;
      }
      
    • 名字空间嵌套

    • 匿名名字空间

      • C++会把声明定义在全局区的标识符通通归纳到一个统一的名字空间中,称为匿名名字空间

      • 直接使用 ::标识符 指定访问全局域中的标识符 (匿名名字空间中的标识符)

        int g = 1024;
        int main(){
            int g = 9527;
            cout << g << endl;
            {
                extern int g;
                cout << g << endl;
            }
            cout << ::g << endl;
            return 0;
        }
        
      • 多文件编程中

        • 声明

          namespace N{
              extern int a;
              void func();
              struct Stu{
                  int no;
                  string name;
              };
          }
          
        • 定义实现

          int N::a;
          void N::func(){
              
          }
          
C++中的函数
  • g++编译器不会再为函数提供隐式函数声明
    • C++调用函数之前,必先声明或定义
  • C语言函数的隐式声明:
    • gcc编译器在编译代码时,如果遇到一个调用的函数在此之前没有定义和声明,则为其隐式声明一个函数,且为其声明函数的返回值类型为int
  • C++函数的形参列表为空 就相当于 C语言中 形参列表为void
C++的函数支持重载
  • 函数重载: 即在同一个作用域下,可以定义同名的函数,但函数的参数列表不同相当

    • 同一个作用域下,函数名相同,参数列表不同即构成重载,在编译调用重载的函数时,会根据实参的个数和类型来绑定调用的函数,静态重载
    • 前提条件:同一个作用域下 如果在不同的作用域,不能构成重载
    • 必要条件:函数名相同,函数列表不同
      • 函数列表不同
        • 参数个数不同
        • 同位置的类型不同
        • 对于指针和引用的类型,常属性不同也能构成重载
          • 如果是非指针和引用,常版本和非常版本会重定义
      • 重载与形参名和返回值类型无关
  • 为什么C++支持重载,而C语言不支持重载

    • g++编译在编译函数时,会对函数进行改名操作 _Zn函数名形参类型简写 _Z3maxii _Z3maxdd _Z3maxiii

    • gcc编译器不会对函数名进行更名操作

    • 可以用 extern “C” 来指定让g++使用C风格的方式来编译函数

      extern "C"   //如果需要在C语言中调用C++的函数,那就必须使用extern "C"来编译C++的代码
      void func(){}
      
      
      extern "C"{
          void f1(){};
          void f2(){}
      }
      
  • 注意调用重载时产生的二义性 (歧义)

    void func(char a,char b){
        
    }
    void func(int a,int b){
        
    }
    
    int main(){
        func('a','b');//有明确类型   没有任何歧义 
        func(1,2);    //没有歧义 
        //func(3.14,5.16);  //歧义   double->char   double->int
        //func('a',5);      //歧义    char,char     int,int
        func('a',3.14);     //没有歧义    char,char  只需要有一个类型隐式转换     
        func(3.14,5);       //int,int 
        return 0;
    }
    
C++的函数支持默认值(缺省值)
  • 在定义函数时,形参可以声明默认值

    • 好像定义变量直接初始化一样
  • 如果一个函数有默认值,则在调用该函数时,可以为该形参传递实参,也可以选择不传,不传则采用默认值

  • 靠右原则

    • 如果一个形参有默认值,则其后面(右边)所有的形参都必要要有默认值
  • 有缺省值注意不要和重载产生歧义(二义性)

    //_Z3barv
    void bar(){
        
    }
    //_Z3barii
    void bar(int a=1,int b=2){
    
    }
    
    //bar();//一调用则产生歧义
    bar(1024);
    bar(9527);
    
  • 如果在函数声明和定义分离,则缺省值只能出现在函数声明中

    void func(int a=1024);
    
    void func(int a){
        
    }
    
C++的函数支持哑元
  • 只有类型,没有形参名谓之哑元

    void func(int){
        
    }
    
    • 在调用哑元函数时,一定要传递一个该类型的实参 只关心类型,不关心值的大小
    • 需要注意和重载的重定义
C++的函数支持内联
  • inline
  • 优化方式 提高代码的运行效率
    • 直接用函数的二进制指定替换函数的调用指令 加快程序执行速度 使可执行程序变大
    • 只是一种申请和建议 取决于编译器
    • 简单且重复调用的函数可以声明为内联函数
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026106.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号