C++入门

在编程的世界中,C++无疑是一颗璀璨的明星。它以其高效、灵活和强大的特性,赢得了无数开发者的青睐。本篇文章旨在为广大初学者提供一个C++入门指南,带你走进C++的世界。

ps:本文只是粗略介绍,详细指南尽情期待

目录

一、C++关键字

二、命名空间

三、C++输入&输出

四、缺省参数

五、函数重载

六、引用

七、内联函数

八、auto关键字

九、基于范围的for循环

十、指针空值---nullptr

十一、总结


一、C++关键字

C++关键字是C++编程语言中预先定义并保留的标识符,用于表示特定的语法结构或控制流。这些关键字在C++程序中具有特殊的含义,不能作为变量名、函数名或其他标识符使用。例如,int、double、if、for、while等都是C++的关键字。理解并正确使用这些关键字是编写C++程序的基础。

二、命名空间

命名空间(Namespace)是C++中为了避免命名冲突而引入的一种机制。通过将相关的类、函数和对象组织在同一个命名空间中,我们可以避免在全局作用域中因命名冲突而导致的问题。例如,std是C++标准库中的命名空间,它包含了如cout、cin等常用的标准输入输出对象。使用命名空间时,我们可以通过::运算符来访问其中的成员,如std::cout。

命名空间的使用有三种方式:

//加命名空间名称及作用域限定符

int main()

{

        printf("%d\n", N::a);

        return 0;    

}

//使用using将命名空间中某个成员引入

using N::b;

int main()

{

        printf("%d\n", N::a);

        printf("%d\n", b); return 0;    

}

//使用using namespace 命名空间名称引入

using namespce N;

int main()

{

    printf("%d\n", N::a);

    printf("%d\n", b);

    Add(10, 20);

    return 0;    

}

三、C++输入&输出

C++中的输入输出操作主要通过流(Stream)来完成。其中,cin用于从标准输入(通常是键盘)读取数据,而cout则用于向标准输出(通常是屏幕)输出数据。此外,C++还提供了许多其他的流对象,如cerr(用于输出错误信息)、clog(用于输出程序运行时的日志信息)等。在使用这些流对象时,我们需要包含头文件<iostream>。

看下C++是如何来实现输出:

#include<iostream>

// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中

using namespace std;

int main()

{

    cout<<"Hello world!!!"<<endl;

    return 0;

}

看下C++是如何来实现输入:

#include<iostream>

using namespace std;

int main()

{

    int a;

    double b;
    
    char c;


    // 可以自动识别变量的类型

    cin>>a;

    cin>>b>>c;

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

    return 0;

}

四、缺省参数

缺省参数(Default Parameter)是C++中一种方便的特性,它允许我们在定义函数时为参数指定默认值。当调用函数时,如果某个参数被省略,则会自动使用其默认值。这种特性可以简化函数调用,提高代码的可读性和可维护性。需要注意的是,缺省参数只能从右往左依次设置,即一个函数中的某个参数有缺省值时,它右边的所有参数都必须有缺省值。

例如:

void Func(int a = 0)

{

    cout<<a<<endl;

}

int main()

{

    Func();    //没有传参时,使用参数的默认值 

    Func(10);  //传参时,使用指定的实参

    return 0;

}

五、函数重载

函数重载(Function Overloading)是C++中一种强大的特性,它允许我们定义多个同名但参数列表不同的函数。在调用这些函数时,编译器会根据传入的参数类型和数量来确定调用哪个函数。这种特性可以使得我们的代码更加简洁和易读。需要注意的是,重载函数的参数列表必须不同,这包括参数的个数、类型或顺序。

当涉及到C++函数重载时,我们可以定义多个同名但参数列表不同的函数。以下是一个简单的C++函数重载的示例代码:

#include <iostream>

#include <string>



// 第一个函数重载版本,接受两个整数并返回它们的和

int add(int a, int b) 
{

    return a + b;

}

// 第二个函数重载版本,接受两个浮点数并返回它们的和

double add(double a, double b) 
{

    return a + b;

}

// 第三个函数重载版本,接受一个整数和一个字符串,并输出它们的拼接结果

void add(int a, const std::string& b) 
{

    std::cout << "The number " << a << " and the string \"" << b << "\" have been passed to add().\n";

}



int main() 
{

    // 调用整数版本的add函数

    int sum_ints = add(3, 4);

    std::cout << "Sum of integers: " << sum_ints << std::endl;

    // 调用浮点数版本的add函数

    double sum_doubles = add(3.14, 2.71);

    std::cout << "Sum of doubles: " << sum_doubles << std::endl;

    // 调用整数和字符串版本的add函数

    add(5, "Hello");

    return 0;

}

在上面的代码中,我们定义了三个名为add的函数,但它们的参数列表不同。第一个函数接受两个整数,第二个函数接受两个浮点数,第三个函数接受一个整数和一个字符串。在main函数中,我们根据传入的参数类型来调用不同版本的add函数,从而实现了函数重载。

编译并运行这段代码,你将看到如下输出:

Sum of integers: 7

Sum of doubles: 5.85

The number 5 and the string "Hello" have been passed to add()

六、引用

引用(Reference)是C++中的一种复合类型,它是对某个变量或对象的别名。通过引用,我们可以直接访问和操作它所引用的变量或对象。与指针相比,引用在语法上更加简洁,且更安全(因为引用一旦初始化后就不能再指向其他变量或对象)。在C++中,我们通常使用引用作为函数的参数或返回值,以便在函数内部直接修改外部变量的值。

当涉及到C++中的引用时,以下是一个简单的示例代码,它展示了如何定义和使用引用:

#include <iostream>



// 一个简单的函数,它接受一个整数的引用作为参数,并修改它

void modifyValue(int& ref) 
{

    ref = 100; // 直接修改引用的值会改变原始变量的值

}



int main() 
{

    int originalValue = 5; // 原始变量

std::cout << "原始值: " << originalValue << std::endl;



    // 创建一个对originalValue的引用

    int& refToOriginal = originalValue;



    // 通过引用修改值

    refToOriginal = 20;

    std::cout << "通过引用修改后的值: " << originalValue << std::endl; // 输出20,因为refToOriginal和originalValue指向同一个内存地址



    // 使用函数来修改值

    modifyValue(originalValue);

    std::cout << "通过函数调用修改后的值: " << originalValue << std::endl; // 输出100



    return 0;

}

在这个示例中,我们首先定义了一个名为modifyValue的函数,它接受一个整数的引用作为参数。然后,在main函数中,我们创建了一个名为originalValue的整数,并通过int& refToOriginal = originalValue;创建了一个对originalValue的引用。接着,我们通过引用修改了originalValue的值,并输出了修改后的结果。最后,我们调用modifyValue函数,该函数也通过引用修改了originalValue的值,并输出了最终的结果。

由于引用是别名,因此任何对引用的修改都会直接影响原始变量。在这个例子中,我们可以看到originalValue的值在程序运行过程中被多次修改,并且每次修改都通过引用进行。

七、内联函数

内联函数(Inline Function)是C++中一种用于提高程序执行效率的特性。当函数被声明为内联时,编译器会尝试在调用该函数的地方将其代码内联展开,从而避免函数调用的开销。需要注意的是,内联函数只是编译器的一个建议,编译器并不一定会遵循这个建议。此外,如果内联函数的代码过长或过于复杂,编译器可能会选择不将其内联展开。

当涉及到C++中的内联函数时,以下是一个简单的示例代码:

#include <iostream>

// 使用inline关键字声明的内联函数
inline int add(int a, int b) 
{
    return a + b;
}

int main() 
{
    // 调用内联函数
    int sum = add(5, 3);
    std::cout << "The sum is: " << sum << std::endl;

    // 通常情况下,编译器会尝试将内联函数的调用替换为函数体本身
    // 但请注意,是否真正内联取决于编译器的优化决策

    return 0;
}

在这个例子中,add函数被声明为内联函数,使用了inline关键字。这意味着编译器在编译时可能会尝试将对这个函数的调用替换为函数体本身,以消除函数调用的开销。然而,是否真正内联取决于编译器的优化决策和上下文(例如,如果函数很大或递归,编译器可能不会内联它)。

内联函数通常用于小型、频繁调用的函数,以减少函数调用的开销。但是,过度使用内联函数可能会导致代码膨胀,因为每个内联函数的调用点都会被替换为函数体本身。因此,在使用内联函数时需要权衡利弊。

另外,值得注意的是,即使使用了inline关键字,也不保证编译器一定会内联该函数。这只是向编译器提出一个建议,编译器有权决定是否采纳这个建议。此外,inline函数必须在调用它的每个文本文件之前被定义,否则编译器无法知道它的内容以进行内联替换。因此,内联函数的定义通常放在头文件中。

八、auto关键字

auto关键字是C++11中引入的一个新特性,它用于自动推导变量的类型。当我们在声明变量时,如果不知道或不想明确指定变量的类型,可以使用auto关键字让编译器自动推导。这种特性可以使得我们的代码更加简洁和易读。需要注意的是,auto关键字只能用于推导局部变量的类型,不能用于推导全局变量或静态变量的类型。

当涉及到C++中的auto关键字时,它通常用于自动类型推导,让编译器根据初始化的表达式来确定变量的类型。以下是一个简单的示例代码,展示了auto关键字的使用:

#include <iostream>
#include <vector>

int main() 
{
    // 使用auto关键字自动推导整型变量的类型
    auto number = 42;
    std::cout << "The number is: " << number << std::endl;

    // 使用auto关键字自动推导初始化为字符串的变量类型
    auto greeting = "Hello, World!";
    std::cout << greeting << std::endl;

    // 使用auto关键字和STL容器(这里是vector)
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    for (auto num : numbers) 
    { // 使用auto推导迭代器指向的元素类型
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    // 使用auto推导lambda表达式返回的类型(C++14及以后)
    auto add = [](int a, int b) { return a + b; };
    std::cout << "Sum of 3 and 4 is: " << add(3, 4) << std::endl;

    // 使用auto推导复杂表达式的类型
    auto complexCalculation = 3.14 * number * number;
    std::cout << "Complex calculation result: " << complexCalculation << std::endl;

    return 0;
}

在这个示例中,我们展示了auto关键字在不同场景下的使用。从简单的整型变量和字符串,到STL容器(如std::vector)的迭代器,再到lambda表达式的返回类型,以及复杂表达式的类型推导。auto关键字使得代码更加简洁,并允许程序员在编写代码时更加关注算法和逻辑,而不是类型本身。

九、基于范围的for循环

基于范围的for循环(Range-based for loop)是C++11中引入的一种新的循环结构,它用于遍历容器(如数组、向量、列表等)中的元素。与传统的for循环相比,基于范围的for循环更加简洁和易读。在使用基于范围的for循环时,我们只需要指定要遍历的容器和循环变量即可,无需关心容器的底层实现和索引管理。这种特性可以使得我们的代码更加简洁和易于维护。

以下是一个简单的示例,展示了如何使用基于范围的for循环来遍历一个std::vector:

#include <iostream>
#include <vector>

int main() 
{
    // 创建一个包含一些整数的vector
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用基于范围的for循环遍历vector中的每个元素
    for (const auto& number : numbers)
    {
        std::cout << number << ' '; // 输出:1 2 3 4 5
    }
    std::cout << std::endl;

    // 如果需要修改元素,可以使用非const引用
    for (auto& number : numbers) 
    {
        number *= 2; // 将每个元素乘以2
    }

    // 再次遍历并打印修改后的vector
    for (const auto& number : numbers) 
    {
        std::cout << number << ' '; // 输出:2 4 6 8 10
    }
    std::cout << std::endl;

    return 0;
}

在上面的代码中,我们创建了一个std::vector<int>并初始化为{1, 2, 3, 4, 5}。然后,我们使用了三个基于范围的for循环:

  1. 第一个循环使用const auto&来遍历元素,确保我们不会意外地修改它们,并输出它们的值。
  2. 第二个循环使用auto&来遍历元素,以便我们可以修改它们。在这个例子中,我们将每个元素都乘以了2。
  3. 第三个循环再次使用const auto&来遍历并输出修改后的元素值。

基于范围的for循环极大地简化了遍历容器或数组的代码,使代码更加简洁易读。

十、指针空值---nullptr

在C++中,我们通常使用NULL或0来表示指针的空值。然而,在C++11中,引入了一个新的关键字nullptr来表示指针的空值。与NULL相比,nullptr具有更好的类型安全性和可读性。首先,nullptr是一个类型安全的指针空值,它可以被隐式地转换为任何指针类型,但不能被转换为非指针类型(如整数)。其次,nullptr的拼写更加直观和易于理解,它明确表示这是一个指针的空值

在C++11及以后的版本中,引入了一个新的关键字nullptr,用于表示指针的空值。在这之前,通常使用整数0或宏NULL来表示指针的空值,但这在某些情况下可能会导致混淆或错误。

nullptr是一个指针字面量,表示空指针,它的类型是std::nullptr_t,但可以隐式转换为任何指针或指针到成员的类型。使用nullptr比使用0或NULL更加直观和清晰,因为它明确地表示一个指针而不是一个整数。

下面是一个简单的示例,展示了如何使用nullptr:

#include <iostream>



int main() {

    int* ptr1 = nullptr; // 声明一个指向int的指针,并将其初始化为nullptr

    if (ptr1 == nullptr) {

        std::cout << "ptr1 is a null pointer" << std::endl;

    }



    // 尝试解引用nullptr会导致运行时错误

    // int value = *ptr1; // 这将是不安全的,并可能导致程序崩溃



    // 与NULL的对比

    int* ptr2 = NULL; // 在C++11之前,这是常见的空指针表示方法

    if (ptr2 == nullptr) {

        std::cout << "ptr2 is also a null pointer" << std::endl;

    }



    // 注意:在C++中,NULL通常被定义为(void*)0或类似的类型,这可能导致一些意外的类型转换

    // 使用nullptr可以避免这种潜在的混淆



    return 0;

}

在这个示例中,我们声明了两个指针ptr1和ptr2,并将它们都初始化为空指针。然后,我们使用nullptr来检查它们是否为空。请注意,尝试解引用nullptr(如取消注释的int value = *ptr1;行所示)将导致运行时错误,因为nullptr表示一个不指向任何有效内存地址的指针。

十一、总结

C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式 等。熟悉C语言之后,对C++学习有一定的帮助,本文主要目标:

1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用 域方面、IO方面、函数方面、指针方面、宏方面等。

2. 为后续类和对象学习打基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值