• C++初阶--C++入门(2)


    C++入门(1)链接入口

    内联函数

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

    //内联函数 inline
    inline int Add(int x, int y)
    {
    	return x + y;
    }
    //不同建立栈帧,提高函数效率
    int main()
    {
    	cout << Add(1, 2) << endl;
    	return 0;
    	//内联函数向编译器发送请求,编译器可以忽略这个请求
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    在这里插入图片描述

    在C语言中,我们会用到宏定义#define 处理一些替换,如简单的函数,复杂的数据,变量名;貌似宏定义与内联函数是相同的;

    但实际上是有很大的区别的:

    内联函数是真实的函数,可以像普通函数一样进行调试、类型调查和自动类型转换。它们可以包含类的成员变量,并且可以在编译阶段将函数嵌入到调用处。而宏定义只是简单的文本替换,不进行类型检查和类型转换,且只是在预编译阶段进行替换,没有任何调错机会,一旦有错误,在编译前就无法实现。

    在这里插入图片描述
    所以,内联函数不要把声明和定义分离开来,最好就在同一文件下进行。

    auto关键字

    在C++11中,,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。也就是说,auto可以自动识别类型

    初步测试:

    int main()
    {
    	int a = 10;
    	char b = 2;
    	double c = 2.0;
    	int* d = &a;
    	float e = 1.0;
    	auto a1 = a;
    	auto b1 = b;
    	auto c1 = c;
    	auto d1 = d;
    	auto* d2 = d;
      auto& d3=d;
     //auto和auto*是没有什么区别的
     //auto进行引用时,就必须使用auto&,因为auto是对类型进行判断,引用相当于别名,所以要加
    	auto e1 = e;
    	cout << typeid(a1).name() << endl;
    	cout << typeid(b1).name() << endl;
    	cout << typeid(c1).name() << endl;
    	cout << typeid(d1).name() << endl;
    	cout << typeid(e1).name() << endl;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    对于目前阶段来说,auto无法体现出真正的价值,但在C++中,定义类型时,有时可不只是一个int或者float可以比的;

    #include
    #include
    
    int main()
    {
    	vector<string> v;
    	vector<string>::iterator it = v.begin();
    	auto it = v.begin();//上下的类型一样
    	//auto在定义对象时,类型较长时,用它很方便
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    注意事项

    不可作为参数

    void func(auto a)
    {
     //auto不可作为参数,编译器无法对a的实际类型进行推导
     //传参的内容是拷贝主参的,所以对于函数来说,都是参数值,无法进行类型推导
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    返回值
    在VS2022中,已经支持auto作为返回值,但最好还是不要用,作为返回值有一定的风险性,如果没有返回值,或者没有参数,那么对于这个函数的返回值是无的。

    //可以作为返回值
    auto func(int a)
    {
    	return a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    同一行多个变量

    //同一行多个变量
    void Testauto()
    {
    	auto a = 1, b = 2;
    	auto c = 1, d = 'd';//错误的
    	//在同一行进行多个变量定义时,必须是类型相同的;因为auto只对第一个变量进行识别判断
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    不可作为数组

    void Testauto()
    {
    	int a[] = { 1,2,3 };
    	auto b[] = { 1,2,3 };//错误的
    	//auto不可用来声明数组
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    基于范围的for循环(C++11)

    对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

    void TestFor2()
    {
    	int array[] = {1,2,3,4,5};
    	//引用e取数组中每个值
    	//e取完一个值后,会自动++1
    
    	
    	cout << array[0] << endl;
    	for (auto& e : array)
    	{
    		cout << e << endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    void TestFor2()
    {
    	int array[] = {1,2,3,4,5};
    	//引用e取数组中每个值
    	//e取完一个值后,会自动++1
    
    	for (auto& e : array)
    	{
    		e *= 2;
    	}
    	cout << array[0] << endl;
    	for (auto& e : array)
    	{
    		cout << e << endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    由于这种范围for比较方便,相对的,使用这种for循环也有一定的条件要求:
    for循环迭代的范围必须是确定的。对于数组而言,就是数组中第一个元素和最后一个元素的范围;
    迭代的对象要实现++和==的操作

    nullptr

    由于在C++中,NULL是这样定义的:
    在这里插入图片描述
    NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量
    我们也可以测试下:

    //nullptr
    void f(int)
    {
    	cout << "f:int" << endl;
    }
    void f(int*)
    {
    	cout << "f:int*" << endl;
    }
    int main()
    {
    	f(0);
    	f(NULL);
    	//结果一样,因为NULL就是0
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    所以就有了nullptr这样的关键字;
    在这里插入图片描述
    注意:

    1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
    2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
    3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
  • 相关阅读:
    【C++ 程序设计入门基础】- Chapter One
    交叉验证太重要了!
    钓鱼邮件又出新花样
    机器人编程学习有哪些好处?
    Java并发—利用AQS实现自定义锁
    iptables实战
    FPGA的主流技术与市场表现方面的调研报告
    2022科大讯飞AI开发者大赛,来了!
    uniapp选择地址弹窗组件
    .NET Core中间件管道MAP的作用和使用
  • 原文地址:https://blog.csdn.net/m0_74068921/article/details/133936382