C++入门必看知识点详解

图片

C++入门

前言:本篇主要叙述了C++中一些关键字和函数的规则和用法,知识比较零碎,较为冗余。

1.C++关键字

C++关键字(C++98):

例子:

小学生写作文:识字—>造句—>写作文

大学生写代码:关键字—>语句—>实现算法逻辑

由于C++中关键字较多,就不一一解释了,后面用到再说:

图片

2.命名空间

在C/C++中,变量、函数、类都大量存在,都存在于全局作用域中,可能会发生冲突。使用命名空间的目的是对标识符的名称进行本地化管理,namespace关键字来实现

代码举例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
namespace ZLJ
{
    int a = 10;
    int b = 20;
    int Add(int left, int right)
    {
        return left + right;
    }
}
int main()
{
    printf("%dn", a);
    printf("%dn", Add(1,2));
    system("pause");
    return 0;
}
图片

这是命名空间就起作用了,这也是一个封装思想(不能为所欲为)

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

1.加命名空间及作用域限定符  

int main()
{
    printf("%dn", ZLJ::a);
    printf("%dn", ZLJ::Add(1,2));
    system("pause");
    return 0;
}

2.使用using将命名空间引入

using ZLJ::a;
using ZLJ::Add;
int main()
{
    printf("%dn", a);
    printf("%dn", Add(1, 2));
    system("pause");
    return 0;
}

3.使用using namespace 命名空间名称引入

using namespace ZLJ;
int main()
{
    printf("%dn", a);
    printf("%dn", Add(1, 2));
    system("pause");
    return 0;
}

3.C++输入&输出

有没有想到刚学习C语言时printf输出的”Hello world”;

使用cout标准输出和cin标准输入,必须包换#include<iostream>std标准命名空间

注意:

1.C++编译时头文件不需要<…h>格式

2.C++输入输出更加方便,不需要增加数据格式控制。例:%d,%c,%f

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int main()
{
    int n;
    cin >> n;
    cout << n << endl;
    cout << "Hello World" << endl;
    system("pause");
    return 0;
}
图片

4.缺省参数

概念:缺省参数是函数声明或定义时为函数的参数提供一个默认值,在调用函数时,如果没有指定实参则采用默认值,否则使用实参

理解:备胎思想,有了就不要你,没有才找你

图片

4.1全缺省参数:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1 = 1, int n2 = 2,int n3 = 3)
{
    return n1 + n2 + n3;
}


int main()
{
    printf("%dn", Add());
    system("pause");
    return 0;
}
图片

4.2半缺省参数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1  , int n2 ,int n3 = 3)
{
    return n1 + n2 + n3;
}


int main()
{
    printf("%dn", Add(1,2));
    system("pause");
    return 0;
}
图片

注意:

1.半缺省参数必须从右向左依次给出,不能间隔给。

2.缺省参数不能同时出现在函数声明和定义中

图片

3.缺省值必须是常亮或全区变量

4.C语言不支持缺省参数

5.函数重载

5.1函数重载的用法

概念:函数名相同,但是其作用和解决的问题不同(自己总结了一下…)

举例:中国奥运会上,乒乓球比赛打完后,我们会佩服的说“谁都赢不了”,看完中国足球比赛后,我们会生气的说“谁都赢不了”,一句话有多种含义。

要求:

相同:

1.函数名相同

2.函数的返回值相同

不同:

1.函数参数的类型或顺序或个数必须不同

2.返回值的参数不同

举例:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
int Add(int n1, int n2)
{
    return n1 + n2;
}
double Add(double n1, double n2 )
{
    return n1 + n2;
}


int main()
{
    cout<< Add(1,2)<<endl;
    cout << Add(1.0, 2.0) << endl;
    system("pause");
    return 0;
}

通过调试就可以看到他们调用的函数不同,注意重载必须要满足要求

图片

比如以上函数参数的类型和个数都相同则无法重载。

5.2 extern关键字

基本理解

extern放在变量或者函数之前,表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

5.2.1extern有两个作用

1.当它与”C”一起连用时,如: extern “C” void fun(int a, int b);告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的(不同编译器不同),因为C++支持函数的重载。

2…在头文件中: extern int g_Int; 它的作用就是声明全局变量或函数的作用范围的关键。

5.2.2extern和static

static的全局变量作用域只在本文件中,所以extern和static不能同时修饰一个变量;

extern 表明该变量在别的地方已经定义过了,在这里要使用那个变量.

static 表示静态的变量,分配内存的时候, 存储在静态区,不存储在栈上面.

extern可以被其他的对象用extern 引用,而static 不可以,只允许对象本身用它.

static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义.

static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,不会影响到其他的单元.

6.引用(重点)

6.1引用概念

引用不新定义一个变量,而是给已存在变量取了个别名,编译器不会为引用变量开辟空间,它和它所引用的变量共用同一块内存空间。

比如:孙悟空,在天上叫“齐天大圣”,成佛后叫”斗战胜佛”

图片

用法:

图片

6.2引用特性

1.引用在定义时必须初始化

2.一个变量可以有多个引用

3.引用一旦引用一个实体,再不能引用其他实体

void TestRef()
{
int  a = 10;
//int& ra; 这是一条错误语句,引用在定义时必须初始化
int& ra = a;
int& rra = a;//一个变量可以有多个引用
cout << &a << endl; 
cout << &ra << endl;
cout << &rra << endl;
}
int main()
{
TestRef();
system("pause");
return 0;
}

其地址空间也是相同的

图片

6.3常引用:

当变量被常变量const修饰后,则只能使用不能改写,其引用也要使用const修饰,成为常引用,否则会报错

图片
void TestRef()
{
const int  a = 10;
//int& ra; 这是一条错误语句,引用在定义时必须初始化
const int& ra = a;
cout << &a << endl; 
cout << &ra << endl;
}
int main()
{
TestRef();
system("pause");
return 0;
}

6.4使用场景

1.做参数

int Add(int& n1, int& n2)
{
    return n1 + n2;
}

int main()
{
    int a = 10;
    int b = 20;
     Add(a, b);
    //TestRef();
    system("pause");
    return 0;
}

2.做返回值

int& TestRef(int& a)
{
a += 10;
return a;
}


int main()
{
int a = 10;
cout<<TestRef(a)<<endl;
system("pause");
return 0;
}

要注意这里引用必须是左值引用(C++11会讲到,现在先不管)

6.5 传值、传引用效率(重点)

这里涉及到深浅拷贝的问题后面再细讲。传引用效率更高

这有一份测试性能的代码

#include <iostream>


#include <Windows.h>


using namespace std;


void test1(string str)


{
string s = str;
}


void test2(string const& str)


{


string s = str;


}
int main()


{
DWORD d;


d = GetTickCount64();
string str = "hello world!";


for (int i = 0; i < 100000; i++)


{


test1(str);


}


cout << "传值用时:" << GetTickCount64() - d << "n";


d = GetTickCount64();


for (int i = 0; i < 100000; i++)


{


test2(str);


}


cout << "传引用用时:" << GetTickCount64() - d << "n";

system("pause");
return 0;
}
图片

6.6指针和引用的区别(重点)

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

int main(
{
int a = 10;
int& ra = a;
cout<<"&a = "<<&a<<endl;
cout<<"&ra = "<<&ra<<endl;
return 0;
}

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}

我们来看下引用和指针的汇编代码对比:

图片

引用和指针的不同点(面试题):

1.引用在定义时必须初始化,指针没有要求

2.引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体

3.没有NULL引用,但有NULL指针

4.在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)

5.引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

6.有多级指针,但是没有多级引用

7.访问实体方式不同,指针需要显式解引用,引用编译器自己处理

8.引用比指针使用起来相对更安全

7.内联函数

7.1 概念

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

图片

7.2特性

1… inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。

2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义 inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。

3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/222079.html

联系我们
联系我们
分享本页
返回顶部