成为大牛第一步 —— C++ 入门基础

目录

        祖师爷——Bjarne Stroustrup

        什么是C++

        C++应用领域

        C++版本更新

        C++的第⼀个程序

        命名空间

        命名空间的定义

        特性

        命名空间成员的调用

        C++的输入&输出

        缺省参数

         注意事项

        缺省函数的定义

        重载函数

        基本概念

引用

        注意

        特性:

        引用的价值

        inline(内联)

        特性

        nullptr


祖师爷——Bjarne Stroustrup

本贾尼·斯特劳斯特卢普(Bjarne Stroustrup,1950年6月11日-),丹麦人,计算机科学家,在德克萨斯A&M大学担任计算机科学的主席教授。他最著名的贡献就是开发了C++程序设计语言。 

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

什么是C++

C++(c plus plus)是一种计算机高级程序设计语言,是C语言的拓展。正所谓青出于蓝而胜于蓝,C++继承了 C 的大多数优点,并增加了面向对象编程(OOP)的功能以及其他的改进

C++的的一些特性可能会使它比 C 更适合某些类型的项目,特别是那些需要高级抽象和复杂系统设计的应用

C++应用领域

  • 大型软件开发,如编译器,浏览器,数据库(相对而言,只有C++适合),操作系统等
  • PC端,军工业,传统工业, C++ && QT等
  • 后端服务开发
  • 游戏后端开发
  • 嵌入式及物联网领域(饭碗),嵌入式驱动(需对硬件了解),学完C++需单独学习嵌入式系统或说stm32
  • 分布式应用
  • 人工智能,上层基本都是用python封装
  • 音视频处理,如ffmeg
  • 测试开发\测试

C++版本更新

标准版本

发布时间

正式名称

更新内容

C++ 03

2003年

ISO/IEC 14882:2003

对C++ 98版本的漏洞做了部分修改。 [14]

C++ 11

2011年8月12日

ISO/IEC 14882:2011

对容器类的方法做了三项主要修改:

1、新增了右值引用,可以给容器提供移动语义。

2、新增了模板类initilizer_list,因此可将initilizer_list作为参数的构造函数和赋值运算符。

3、新增了可变参数模板(variadic template)和函数参数包(parameter pack),可以提供就地创建(emplacement)方法。 [15]

C++ 14

2014年8月18日

ISO/IEC 14882:2014

C++11的增量更新。主要是支持普通函数的返回类型推演,泛型lambda,扩展的lambda捕获,对constexpr函数限制的修订,constexpr变量模板化等。 [18]

C++ 17

2017年12月6日

ISO/IEC 14882:2017

新增UTF-8 字符文字、折叠表达式(fold expressions):用于可变的模板、内联变量(inline variables):允许在头文件中定义变量;在if和switch语句内可以初始化变量;结构化绑定(Structured Binding):for(auto [key,value] : my_map){…};类模板参数规约(Class Template Argument Deduction):用pair p{1, 2.0}; 替代pair{1, 2.0};;>;static_assert的文本信息可选;删除trigraphs;在模板参数中允许使用typename(作为替代类);来自 braced-init-list 的新规则用于自动推导;嵌套命名空间的定义;允许命名空间和枚举器的属性;新的标准属性:[[fallthrough]], [[maybe_unused]] 和 [[nodiscard]];对所有非类型模板参数进行常量评估;Fold表达式,用于可变的模板;A compile-time static if with the form if constexpr(expression);结构化的绑定声明,允许auto [a, b]=getTwoReturnValues()

C++ 20

2020年12月7日

ISO/IEC 14882:2020

新增模块(Modules)、协程(Coroutines)、范围 (Ranges)、概念与约束 (Constraints and concepts)、指定初始化 (designated initializers)、操作符“<=> != ==”;constexpr支持:new/delete、dynamic_cast、try/catch、虚拟、constexpr向量和字符串;计时:日历、时区支持。 

 


C++的第⼀个程序

C++兼容大部分C语言的语法,在Visual Studio2022中,编译.cpp文件使用C++编译器,.c文件使用C编译器;在 Linux 系统下,cpp使用g++编译器,c使用gcc编译器(本文使用vs2022)

//C语言
#include<stdio.h>

int main()
{
    printf("hello world\n");
    return 0;
}
//C++

#include<iostream>
using namespace std;

int main()
{
    std::cout << "hello world" << std::endl;
    return 0;
}

以上两段代码的表现形式是一样的,但编写的代码有很大的差池。C++使用了 cout 对象和 endl 来完成这一任务。 cout 是C++标准库 iostream 中的一个对象,用于向屏幕输出数据;而 endl 则是一个流操纵符,它不仅会输出一个换行符,还会刷新缓冲区。注意,在C++中,我们通常会在 iostream 头文件之前加上 using namespace std; 声明,以便于直接使用 std 命名空间内的元素,比如 cout endl


命名空间

上述代码中提到了命名空间

//使用命名空间std
using namespace std;

当你在程序中使用 using namespace std; 时,实际上是告诉编译器你打算使用标准库中的所有命名空间成员,并且不再每次使用它们时都加上 std:: 前缀。这意味着你可以直接使用 cout  endl 等标准库中的标识符,而不需要每次都写 std::cout std::endl 

💡tips:我比较建议加上 std:: 前缀以防止重定义错误(两个命名空间有同名函数)

命名空间的定义

特性

  • 命名空间内可以定义变量 / 函数 / 结构体等
  • 可以嵌套定义
  • 本质是定义一个域,这个域跟全局域各自独⽴,不同的域可以定义同名变量
  • 多文件定义同名域被认为是同一个域
namespace  xxx
{
    //命名空间中可以定义变量/函数/类型
    int val =10;

    int Add(int left,int right)
    {
        return left + right;
    }

    struct Node
    {
        struct Node* next;
        int val;
    };
}

命名空间成员的调用

namespace xxx
{
    //......
} 

xxx :: func(x,y);
//.......

但在定义结构体时需要注意

struct xxx :: MyStruct node;

xxx :: MyStruct node1; 

将空间内某成员展开

using xxx::val;

C++的输入&输出

<iostream>input output stream的缩写,标准的输入、输出流库,定义了相应对象

  •  std::cin istream 类的一个对象
  •  std::cout ostream 类的一个对象

以上都是针对窄字符的标准输入输出流  

  •  std::endl 换行的同时,刷新缓存区
  • << 流插入运算符,>> 流提取运算符(可以左移/右移)
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

int main()
{
    int a = 0;
    double b = 0.1;
    char c = 'x';

    cout << a << " " << b << " " << c << endl;
    std::cout << a << " " << b << " " << c << std::endl;

    // 可以⾃动识别变量的类型
    cin >> a;
    cin >> b >> c;
    cout << a << endl;
    cout << b << " " << c << endl;
    return 0;
}

缺省参数

缺省参数(Default Arguments),也称为默认参数,在 C++ 中允许你在函数声明或定义时为函数参数提供一个缺省值。当调用函数时如果没有传递对应的实参,则会使用这个缺省值

 注意事项

  • 从右向左定义:缺省参数必须从函数参数列表的右侧向左侧定义。如果你为一个参数定义了缺省值,那么在其右侧的所有参数也必须有缺省值或提供实参。
  • 重复定义:如果你在函数声明和定义中都指定了相同的缺省值,编译器通常会接受这种情况,但最好保持一致性,避免潜在的错误。
  • 缺省参数的顺序:在调用函数时,如果没有提供某个参数,则该参数及其右侧的所有参数都必须使用缺省值或完全提供。
//缺省参数
namespace func
{
	int func1(int a = 1)
	{
		return a++;
	}

	void func2(int a = 10, int b = 20, int c = 30)
	{
		cout << a << endl;
		cout << b << endl;
		cout << c << endl;
	}
}

using namespace func;

int main()
{
	func2();
	func2(1);
	func2(1,2);
	func2(1,2,3);

	return 0;
}

缺省函数的定义

缺省参数在头文件的声明不可以出现缺省!!!会出现重定义错误,在声明给缺省的形参

头文件中

void func(int x, size_t y = 10);

源文件中

void func(int x, size_t y ) {
	//..........
}

重载函数

基本概念

  • 函数名相同:重载的函数必须拥有相同的函数名。

  • 参数列表不同:至少一个参数的类型、数量或顺序不同。

  • 返回类型无关:返回类型的不同不能作为函数重载的依据。即,仅靠返回类型的不同不能区分重载的函数

  • #include <iostream>
    using namespace std;
    
    // 函数重载示例
    void display(int value) {
        cout << "整数值:" << value << endl;
    }
    
    void display(double value) {
        cout << "浮点数值:" << value << endl;
    }
    
    void display(int a, int b) {
        cout << "两个整数值:" << a << " 和 " << b << endl;
    }
    
    int main() {
        display(5);          // 调用 display(int)
        display(5.0);        // 调用 display(double)
        display(5, 10);      // 调用 display(int, int)
        return 0;
    }

    引用

一种特殊类型的变量,它为已经存在的变量提供了一个别名(alias)。一旦创建了引用,它就始终指向最初绑定的对象。引用本身并不是一个新的存储单元;它只是一个已存在对象的另一个名字。

注意

  • 引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
  • 引⽤返回值的场景相对⽐较复杂,我们在这⾥简单讲了⼀下场景,还有⼀些内容后续类和对象章节中会继续深⼊讲解。
  • 引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引⽤跟其他语⾔的引⽤(如Java)是有很⼤的区别的,除了⽤法,最⼤的点,C++引⽤定义后不能改变指向,
  • Java的引⽤可以改变指向。
  • ⼀些主要⽤C代码实现版本数据结构教材中,使⽤C++引⽤替代指针传参,⽬的是简化程序,避开复杂的指针,但是很多同学没学过引⽤,导致⼀头雾⽔。

特性:

  • 定义必须初始化(否则编译出错)
  • 一个变量可以有多个引用
  • 一个引用一但绑定一个实体,不可再改变
int a = 0;
int& b = a;

引用的价值

        引用传参、引用返回值,减少拷贝时的内存占用;改变引用对象,被绑定的对象发生变化

  • 引用可绑定 const 修饰对象,但必须是 cons t引用
  •  const 修饰的对象具有常性,只可读不可写
  • C++规定,相加 || 类型转换会产生临时变量
  • 指针会出现空指针和野指针,引用相对较少,安全性更高
//可以
const int a = 10;
const int& ra = a;

//可以
int b = 10;
const int rb = b;

//不可以,编译无法通过
const int c = 10;
int& rc = c;
  • 引用权限不可大于被绑定变量
  • 引用可以给常量取别名,但是需要const修饰

inline(内联)

特性

  • inline修饰的函数叫内联函数,内联类似于C语言的宏,但是比宏更加安全
  • 内联函数在被调用时展开,因此不需要建立栈帧,可提高效率
  • 内联函数确确实实是一个函数,在编译时会进行类型等检查,因此可提高安全性
  • C语言的宏难以调试,但内联函数可调试
  • inline对编译器来讲只是一个建议,在不同编译器在有不同的效果,有的编译器可以不展开,inline适合比较短小且频繁调用的场景;递归,较长篇幅的函数中,编译器会忽略inline
  • 不建议声明定义分离,会导致链接错误。因为内联函数默认是展开,并没有地址,但头文件中需要拿到函数的地址,在汇编中需要call函数的地址,但内联函数无地址,所以导致链接错误。建议直接放到头文件(.h)

对内联函数进行定义需进行以下操作(以vs2022为例)

#include <iostream>
using namespace std;

// 内联函数声明
inline int max(int a, int b) {
    return (a > b) ? a : b;
}

int main() {
    int a = 20;
    int b = 10;
    int c = 15;
    
    // 多次调用 max 函数
    cout << "Max of " << a << " and " << b << " is " << max(a, b) << endl;
    cout << "Max of " << a << " and " << c << " is " << max(a, c) << endl;
    
    return 0;
}

nullptr

C语言中的NULL实际是⼀个宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码:

#ifndef NULL
    #if defined(__cplusplus)
        #define NULL 0
    #else
        #define NULL ((void *)0)
    #endif
#endif
  • C++中 NULL 可能被定义为字⾯常量0,或者 C 中被定义为⽆类型指针 (void*) 的常量。不论采取何种定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过 f(NULL) 调⽤指针版本的f(int*) 函数,但是由于 NULL 被定义成0,调⽤了 f(intx) ,因此与程序的初衷相悖。f((void*)NULL) ; 调⽤会报错。
  • C++11中引⼊ nullptr nullptr 是⼀个特殊的关键字,nullptr 是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr 定义空指针可以避免类型转换的问题,因为nullptr 只能被隐式地转换为指针类型,⽽不能被转换为整数类型。
#include <iostream>
using namespace std;

void f(int x) {
    cout << "f(int x)" << endl;
}

void f(int* ptr) {
    cout << "f(int *ptr)" << endl;
}

int main()
{
    f(0);

    // 本想通过f(NULL)调用指针版本的f(int*)函数,
    // 但由于NULL被定义成0,调用了f(int x),因此与程序初衷相悖。
    f(NULL);
    f((int*)NULL);

    // 编译报错:error C2665:“f”:2 个重载中没有一个可以转换所有参数类型
    // f((void*)NULL);

    f(nullptr);

    return 0;
}

### 回答1: 本章主要针对初学者,简要介绍了c/c++的基本语法和常见的编译错误。首先,介绍了程序的基本结构和常用的数据类型。c语言的基本语句包括赋值语句、条件语句和循环语句等,这些语句都可以组成程序的逻辑结构。接下来,介绍了函数的定义和调用,以及参数传递的方式。对于c++,还介绍了一些面向对象的概念,例如类、对象、成员函数等。同时,也提到了头文件和命名空间的使用方法。 在编程过程中,常常会出现各种编译错误,例如语法错误、类型不匹配、语义错误等,需要学会如何查看和解决这些错误。此外,还介绍了调试工具和各种常用的运算符和表达式,这些都是初学者必须掌握的基础知识。 总的来说,本章是关于c/c++快速入门的一篇简介性文章。虽然只是涉及到了基础的语法和知识点,但对于初学者而言是一个很好的起点。在学习过程中需要不断实践,积累经验,并不断深入了解更高级的编程技术和工具。 ### 回答2: C/C++是一种广泛使用的编程语言,它具有高效、灵活、可移植等特点,在各个领域得到广泛应用。C语言C++语言基础,在学习C++之前,需要先掌握C语言基础知识。 本文介绍的是C/C++教程中的第二章——快速入门C/C++。在这一章节中,我们将介绍C语言的基本语法、变量、运算符和流程控制语句等基础知识。以下是C语言的一些基本知识点。 C语言的基本语法: C语言程序由多个函数组成,其中一个函数必须命名为main(),程序从该函数开始执行。C程序中的语句以分号结束,注释使用“//”表示单行注释,“/* */”表示多行注释。 变量和数据类型: C语言中变量的定义格式为“数据类型 变量名”;数据类型包括基本类型和用户自定义类型。C语言中的基本类型有int类型、char类型、float类型和double类型等。其中,int类型表示整型,char类型表示字符型,float类型和double类型表示浮点型。 运算符: C语言中的运算符包括算术运算符、关系运算符、逻辑运算符等。例如,“+”表示加法运算符,“>=”表示大于等于运算符,“&&”表示逻辑与运算符。 流程控制语句: C语言中的流程控制语句包括if语句、switch语句、while语句、do-while语句和for语句等。这些语句可以根据条件执行相应的语句块。 总之,本章节的快速入门C/C++,具有基本语法、变量、运算符和流程控制语句等基础知识。初学者可以通过这些基础知识,轻松入门C/C++,为后续学习打下基础。同时,要注意编写代码的规范和逻辑性,才能更好的理解和使用C/C++语言。 ### 回答3: C语言是一门广泛使用的编程语言,具有高效、灵活、稳定等特点,被广泛应用于嵌入式系统、操作系统、驱动程序、多媒体应用等领域。学习C语言是程序员的必备技能之一。 第二章的快速入门C/C++教程,主要介绍了C/C++语言基础知识,重点是程序的结构和输入输出。其中程序结构包括函数、语句、变量、表达式等,而输入输出则包括scanf、printf、getchar和putchar等函数。 # 程序结构 程序结构是指程序的基本构成单元,包括函数、语句、变量、表达式等。C语言中的程序结构主要包含以下几个方面。 ## 函数 C语言中,函数是程序的基本组成单元。一个C程序可以由一个或多个函数组成,每个函数可以完成一个任务。函数的格式如下: ```c 返回类型 函数名(参数1, 参数2, ...){ // 函数体 return 返回值; } ``` 其中,返回类型指函数执行后的返回值类型;函数名是由程序员定义的,用于调用函数时识别函数;参数列表是函数的输入参数,可以有多个参数,每个参数由类型和变量名组成;函数体是函数要执行的代码块;return语句可以返回函数的执行结果。 ## 语句 语句是完成特定功能的一组指令。C语言中的语句包括赋值语句、条件语句、循环语句等。C语言中通常使用花括号来表示语句块。例如,下面是一个if语句的例子。 ```c if(条件){ // if语句块 }else{ // else语句块 } ``` 如果条件为真,则执行if语句块中的代码;否则执行else语句块中的代码。 ## 变量 变量是用于存储数据的一种容器。在C语言中,一个变量包括变量名、类型和值。变量名由程序员定义,用于识别变量;类型指变量的数据类型,如整型、字符型、实型等;值是存储在变量中的数据。变量的定义格式如下。 ```c 数据类型 变量名 = 值; ``` 例如,下面是一个整型变量的定义。 ```c int num = 10; ``` ## 表达式 表达式是由变量、运算符和常量组成的一个具有返回值的语句。C语言中的运算符分为算术运算符、关系运算符、逻辑运算符等,例如加号、减号、乘号、除号等。下面是一个简单的表达式。 ```c a = 5 + 6 * 3 / 2 - 1; ``` 这个表达式将计算5加6乘3除以2减1的值,并将结果赋给a变量。 # 输入输出 输入输出是程序中非常重要的部分,可以让程序与用户进行交互。C语言中有多种输入输出函数,其中一些最常用的是scanf、printf、getchar和putchar函数。 ## scanf函数 scanf函数用于从标准输入读取格式化数据,并将读取的数据存储到变量中。它的格式如下。 ```c scanf("格式控制字符串", 变量列表); ``` 其中,格式控制字符串指示scanf函数需要读取的数据类型和格式,变量列表指向要读取的变量。下面是一个scanf函数的例子。 ```c int num; scanf("%d", &num); ``` 这个代码段将从标准输入读取一个整数,并将其存储到num变量中。 ## printf函数 printf函数用于将格式化数据输出到标准输出。它的格式如下。 ```c printf("格式控制字符串", 参数列表); ``` 其中,格式控制字符串指示printf函数需要输出的数据类型和格式,参数列表包含要输出的变量和常量。下面是一个printf函数的例子。 ```c int num = 5; printf("num的值是%d\n", num); ``` 这个代码段将输出“num的值是5”。 ## getchar和putchar函数 getchar函数用于从标准输入读取一个字符,putchar函数用于将一个字符输出到标准输出。它们的用法非常简单,例如下面的代码将读取一个字符并将其转换成大写字母后输出。 ```c char c = getchar(); putchar(toupper(c)); ``` 以上就是第二章中的快速入门C/C++教程的主要内容,包括程序结构和输入输出方面的基础知识。熟练掌握这些内容,对于学习C语言来说是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值