C++语言基础——序言

C++编程语言是一门非常灵活的编程语言,因此很多人会觉得其非常难,其实主要打好基础,那么这个灵活会给我们天马行空的思想提供帮助。学习C++我觉得需要有一位挚友,就是他大佬。

目录

1. C和C++的渊源

2. C++的历史

3. 风格与命名规范

3.1 程序员的派别

3.2 类名命名

3.3 变量

3.3 函数

4. C++入门预告

4.1 命名空间

4.2 输入输出    

4.3 缺省参数

4.4 函数重载

4.5 引用

4.6 内联函数

4.7 auto

4.8 基于范围的for循环

1. C和C++的渊源

    1982年,Bjarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了一种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此:C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

2. C++的历史

    1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是在C语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with classes。带类的C。
    1983年8月, 第一个C++实现投入使用。Rick Mascitti建议命名为CPlusPlus,即C++。
    1985年第一个C++ Release E发布。CFront的第一个商业发布,CFront Release 1.0。
    1989年,C++再次版本更新,这次更新引入了多重继承、保护成员以及静态成员等语言特性
    1998年,C++标准委员会发布了C++语言的第一个国际标准—ISO/IEC 14882:1998,该标准即为大名鼎鼎的C++98,以模板方式重写C++标准库,引入了STL(标准模板库)
    2003年,标准委员会针对98版本中存在的诸多问题进行了修订,修订后发布了C++03。
    2011年中,C++11面世。增加了许多特性,使得C++更像一种新语言,包括正则表达式、完备的随机数生成函数库、新的时间相关函数,原子操作支持、标准线程库、新的for语法、auto关键字、新的容器类、更好的union支持、数组初始化列表的支持以及变参模板的支持等等。
    后面的都是对C++进行优化了

3. 风格与命名规范

对于风格来说,在学习编程的同学最好能统一自己的风格,比如换行与否,空格与否。在工作的同学与团队的风格保持一致即可。

我们在写代码的时候,优秀的命名习惯能让自己和他人容易的阅读和理解其中的思路,对于工作的来说,通常在团队内都有统一的命名规范来强制约束,因为这样有利于提高工作效率。当然对于还在学习编程的同学来说,我们对于前面不规范的命名需要有所纠正,对于C++内容繁多,更要注意命名方式,避免把自己绕进去。

以下均是个人习惯作为参考,不是标准。

3.1 程序员的派别

  • 大括号是否换行
// 不换行
if () {
// ……
}
// 换行
if ()
{
// ……
}
  • 缩进是空格还是TAB
  • 其余待大家评论补充

3.2 类名命名

每个单词首字母均大写,并以驼峰命名法分割单词,不包含下划线,类, 结构体, 类型定义 (typedef), 枚举 —— 均使用相同约定

class ClassTest {
    ……
}

3.3 变量

 普通变量:尽量为变量起一个描述性的名字。因为能让新的代码阅读者立即理解你的代码。变量名可以采取驼峰写法。
类的成员变量:类的成员变量以m+下划线(m_表示成员)开始, 结构体同普通变量。这样是为了同普通变量区分。当然你也可以直接以下划线开始,与局部变量进行区分。
全局变量:以g (global) 开头,驼峰写法

class ClassTest {
   int _nameStr; // 类的成员变量
}

ing func() {
    String nameStr; // 普通变量
}

String gNameStr = "nameStr";

// 单行注释格式可以是(如上所示): 空格 + // + 空格 + 描述

3.3 函数

函数名的每个单词首字母大写, 没有下划线。

class ClassTest {
    ClassTest(); // 构造函数同类名
    
    void FunTest(); // 普通函数
}

以上常用命名,具体请参考 c++命名规则
    谷歌命名。(我用的谷歌,类成员是以下划线结尾的)

4. C++入门预告

4.1 命名空间

    C++为了防止命名冲突,引入namespace关键字
    一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
    命名空间的三种使用方式

namespace Test {
    int number;
    char flag;;
}
Test::number; // 这个是在要用的时候用
using namespace Test;// 这个时候不能再定义和命名空间内相同的变量名的变量,例如不能再定义a。会造成命名冲突(所以不建议展开,命名空间本就是解决命名冲突的)
using Test::flag;// 这个是展开这个变量
::作用域限定符。

4.2 输入输出    

在C语言中输入输出包含着stdio.h的头文件里,在C++里包含着iostream里。但是它们都在std这个命名空间里,如果没有展开命名空间,需要在使用的地方std::cout,std::cin。

如果觉得这样太麻烦,可以 using namespace std 展开命名空间,直接使用

cout << 变量1 << 变量2 <<endl  

<< 就像传送带一样,给cout输送,所以先输出变量1,在输出变量2,最后是是换行符

 cin >> 变量1 >> 变量2 

这个是把标准输入先给变量1,再给变量2。总之谁离得近,谁就先。

另外提示:命名空间的展开需要谨慎,因为命名空间的存在就是为了防止命名冲突,直接全部展开,就让命名空间失去了作用。

4.3 缺省参数

在参数列表对参数进行默认值定义,即在调用函数时,即使没有传入参数,会通过默认值进行运算

int Sum(int n1 = 10, int n2 = 20) { // 全缺省 
    return n1 + n2; 
}    
int Sum(int n1 , int n2 = 20) // 半缺省
// 缺省从右往左一次赋值,中间不能有间隔  
int Sum(int n1 = 10, int n2) //这样是不可以的,要从右往左,依次赋值
 
   
// 不能在函数申明和定义是同时有缺省参数。如下:编译器也不会通过    
int Sum(int n1 = 10, int n2 = 20);
int Sum(int n1 = 10 , int n2 = 20 ) {
    return n1 + n2;
}

4.4 函数重载

同一个函数名,参数列表不同:顺序(类型不同的参数),类型,数量将构成函数重载,(只有同一个作用域)。
在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern "C",声明是C代码
为什么C语言没有函数重载呢?因为C++在底层对函数有函数签名机制。

int Fun2(int n1, char n2);
      "int __cdecl fun2(int,char)" (?fun2@@YAHHD@Z)
    _z3Add
extern "C" int Fun3(int n1,int n2);

   在底层,C语言对函数只是加了一个下划线,和名字的长度,而C++底层对桉树进行了修饰函数的名字以及参数类型。所以C语言不能实现函数的重载

4.5 引用

    在语法上是引用实体的一个别名,没有独立空间。但是在底层是由独立空间的,是通过指针实现的

    类型& 变量 = 引用实体
    int ka = 10;
    int& ra = ka;

注意:
    必须初始化
    一个变量可以有多个引用
    一个引用只能有一个变量


const int ka = 10;
//int& ra = ka;   // 该语句编译时会出错,a为常量
const int& ra = ka;
// int& kb = 10; // 该语句编译时会出错,b为常量
const int& kb = 10;
double kd = 12.34;
//int& rd = kd; // 该语句编译时会出错,类型不同
const int& rd = kd;

 使用场景:做参数、做返回值

void Swap(int& a, int& b) {
   int temp = a;
   a = b;
   b = temp;
}
int& Retu(int& a) {
    a += 10;
    return a;    
}

 做返回值:引用的生命周期大于函数的生命周期

引用和指针的区别:

  1. 引用必须初始化,指针不用
  2. 引用只能有一个实体,指针可以指向任意一个实体
  3. sizeof中,引用是实体类型的大小,指针在32位平台下是4个字节
  4. 引用++:实体++;指针++:偏移到下一个位置
  5. 有多级指针,没有多级引用

4.6 内联函数

    以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。

  1. 内敛函数对编译器只是个建议,如果函数代码太长或是有循环递归等,编译器还是会开栈
  2. 内敛函数不建议声明和定义分开,会导致链接错误

4.7 auto

    类型占位符编译器自动推导类型
    如果一行定义多个变量,类型要一致,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量

  1. auto不能做为函数的参数
  2.  auto不能直接声明数组
  3. 实例化模板时不能作为模板参数
  4. 不能定义成员变量

4.8 基于范围的for循环

    for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
    对于已确定长度数组而言,我们不用在循环条件上加上限制,避免错误
    条件:长度确定,对象可以++和==

void MyFor() {
    int arr[] = { 1,2,3,8,9,6,4 };
    for (auto& a : arr) {
        cout << a << "\t";
    }
    cout << endl;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值