C++入门
- 一.前言
- 二.缺省参数
- 三.函数重载
- 四.引用
-
- 1.引⽤的概念和定义
- 2.引⽤的特性
- 3.引⽤的使⽤
- [4. const引⽤](#4. const引⽤)
- 5.指针和引⽤的关系
- 五.inline(内联)
- 六.nullptr

一.前言
C++的存在,弥补了C语言中的很多不足,作为面向对象的语言,在使用上会便利很多。这点的本文中会有很好的体现。
二.缺省参数
什么是缺省参数?
- 缺省参数是指在函数声明或定义中为某些参数指定默认值。当调用该函数时,如果省略了这些参数,编译器会自动使用默认值。缺省参数通常用于提供函数的默认行为,同时允许用户根据需要覆盖这些默认值。
cpp
void Func(int a = 10)
{
cout << a << endl;
}
int main()
{
Func();
Func(20);
return 0;
}
以上是对缺省参数的举例,输出为10 20 很显然当我们没有对该函数传参时,所使用的是所给定的默认值10,当我们传20时,此时a所使用的是我们给予的20.
- 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。
cpp
void Func(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
int main()
{
Func();
Func(1,2,3);
Func(1, 2);
return 0;
}
Func(1,2)
就是半缺省,这样只给予了a,b指定的值,而c所使用的仍然是默认给定的值。
- 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。
在这里要注意的是第二点,从左到右以此缺省
。例如Func(1, , 3)
这么做是不被允许的。
- 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。
在将头文件单独分离成为一个文件时,为避免一系列不必要的麻烦,缺省值一般在定义时给出,这是声明处就不能给缺省值,否则会报错。
三.函数重载
为方便使用,C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。
一.传参类型不同
cpp
int ADD(int a, int b)
{
cout << a + b << endl;
return a + b;
}
double ADD(double c, double d)
{
cout << c + d << endl;
return c + d;
}
int main()
{
int a = 1;
int b = 2;
double c = 0.1;
double d = 0.2;
ADD(a, b);
ADD(c, d);
return 0;
}
//输出结果为3 0.3
在这里,同一个函数名ADD
调用了两个不同的函数,这就是函数重载的体现。
由于一个传的参数是int int 类型,所以便会调用第一个ADD函数;同理第二个调用了第二个ADD函数。
2. 传参个数不同
cpp
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
int main()
{
int a = 0;
f();
f(a);
return 0;
}
这里f()
构成了重载。这里的重载是由于所传的参数个数不同,第一个f函数传了0个参数,调用了第一个f函数,而第二个传过去1个参数,所以调用用第二个f函数。
3.传参顺序不同
cpp
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
这里调用时,传参的类型char 和 int 的顺序不同的话,所调用的也是两个不同的函数。
注意点
返回值不同,而参数相同的函数不能构成重载函数。
四.引用
1.引⽤的概念和定义
引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,它和它引⽤的变量共⽤同⼀块内存空间。
引用的格式:类型& 引⽤别名 = 引⽤对象;
cpp
int main()
{
int a = 0;
int& b = a;
int& c = b;
return 0;
}
在这里,b就是a 的别名。同理 c 是 b 的别名,即为 a 的别名。他们所指向了同一块内存空间。
2.引⽤的特性
• 引⽤在定义时必须初始化
• ⼀个变量可以有多个引⽤
• 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体
3.引⽤的使⽤
• 引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被引⽤对象。
• 引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。
注:由于在C语言中,形参的改变不影响实参,所以我们想要改变实参时就需要传指针过去,进行解引用等等。而在c++中,我们由于有引用的存在,在这里我们可以直接传引用,来改变实参。
引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引⽤跟其他语⾔的引⽤(如Java)是有很⼤的区别的,除了⽤法,最⼤的点,C++引⽤定义后不能改变指向,Java的引⽤可以改变指向。
4. const引⽤
• 可以引⽤⼀个const对象,但是必须⽤const引⽤。const引⽤也可以引⽤普通对象,因为对象的访问权限在引⽤过程中可以缩⼩,但是不能放⼤。
不过需要注意的是类似
cpp
int& rb = a*3; (a*3在这里具有常性,直接取别名的话涉及权限的放大)
double d = 12.34;
int& rd = d;(这里在将double 类型转为int 类型时,也是先转成了一个具有常性的量)
这样⼀些场景下a*3的和结果保存在⼀个临时对象中, int& rd = d 也是类似,在类型转换中会产⽣临时对象存储中间值,也就是时,rb和rd引⽤的都是临时对象,⽽C++规定临时对象具有常性,所以这⾥就触发了权限放⼤,必须要⽤常引⽤才可以。所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象,C++中把这个未命名对象叫做临时对象。
5.指针和引⽤的关系
C++中指针和引⽤就像两个性格迥异的亲兄弟,指针是哥哥,引⽤是弟弟,在实践中他们相辅相成,功能有重叠性,但是各有⾃⼰的特点,互相不可替代。
• 语法概念上引⽤是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。
• 引⽤在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
• 引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。
• 引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。
• sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)
• 指针很容易出现空指针和野指针的问题,引⽤很少出现,引⽤使⽤起来相对更安全⼀些。
五.inline(内联)
一、什么是inline函数?
inline函数是一种特殊的函数,它允许编译器将函数调用替换为函数体本身。这样可以减少函数调用的开销,尤其是在处理频繁调用的小函数时,从而提高程序的运行效率。
二、为什么使用inline函数?
- 减少函数调用开销
函数调用通常涉及一些额外的开销,如保存和恢复寄存器状态、跳转到函数地址等。对于频繁调用的小函数,这些开销可能会显著影响程序的性能。通过将函数声明为inline,可以减少这些开销,提高程序的运行效率。 - 提高代码性能
inline函数特别适用于那些频繁调用的小函数,如简单的数学运算或逻辑判断。通过将这些函数的调用替换为函数体本身,可以显著减少函数调用的开销,从而提高程序的性能。 - 简化代码
inline函数可以将一些简单的操作封装为函数,使代码更加清晰和易于维护。同时,由于inline函数的调用开销较小,不会对性能产生负面影响。
三.inline函数的使用方法
- 声明inline函数
inline函数可以在函数声明时使用inline关键字。inline关键字可以出现在函数声明或定义中,但通常建议在函数定义中使用。 - inline函数的定义
inline函数的定义可以放在头文件中,也可以放在源文件中。如果放在头文件中,可以确保多个源文件中使用相同的inline函数定义。 - inline函数的调用
inline函数的调用方式与普通函数相同。编译器会根据函数的定义和调用情况决定是否将函数调用替换为函数体。
注意
- 编译器的决定权
虽然使用inline关键字可以建议编译器将函数调用替换为函数体,但编译器有权决定是否接受这个建议。如果函数体过大或调用次数过少,编译器可能会忽略inline关键字。
六.nullptr
NULL实际是⼀个宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码:
cpp
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,⽽不能被转换为整数类型。
cpp
void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int* x)
{
cout << "f(int* x)" << endl;
}
例如上述情况,当我们在传NULL时,会调用的时第一个函数(可见宏定义),为避免歧义,引入了nullptr。