欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > c++入门

c++入门

2025/11/22 10:00:40 来源:https://blog.csdn.net/kukubuzai/article/details/145671249  浏览:    关键词:c++入门

前言

c++的出现主要最初是为了解决c语言的不足,但随着之后逐渐的发展,成为了一门成熟的语言。因为,c++最初是为了解决c语言的不足。所以,在c++入门学习主要了解c++解决那些c语言的不足。

命名空间namespace

c语言很大的一个缺点就是,他的很多库里的函数名和我们命名的变量等数据的名字出现了冲突。而前,很多时候我们需要多个文件,这多个文件不同的变量命很容易出现名字的冲突,这就很难受。所以,c++提出了一个新的概念命名空间,它的关键词是namspace。他是独立于全局域和局部域的一个独立区域。这个域是封装起来的。就是说,如果你没有展开这部分域,它里面的成员你是无法使用的。编译器不会主动取寻找。除非你指定了这个域。

namespace cll
{int x;int Add(int a,int b){return a + b;}struct SListNode{int data;struct SListNode* next;};namespace bdd{int x;}
}//这里不需要分号

这里就是一个命名空间的创建,命名空间的成员可以是变量,函数,自定义类型,还可以是命名空间,也就是说一个命名空间里面还可以有很多其他命名空间。

展开域

展开域的关键词是using,

namespace cll
{int x;int Add(int a,int b){return a + b;}struct SListNode{int data;struct SListNode* next;};namespace bdd{int x;}
}//这里不需要分号
using namespace cll;int main()
{int ret = Add(1, 2);printf("%d", ret);return 0;
}

这里如果你没有展开域,你是不能使用这个域里面的成员函数的。如果你分要使用这个成员函数,你可以指定域。

域作用限制符 ::

域作用限制符 ::使用

域名 + ::

如果前面没有域命,那就是全局域。

namespace cll
{int x;int Add(int a,int b){return a + b;}struct SListNode{int data;struct SListNode* next;};namespace bdd{int x;}
}//这里不需要分号
//using namespace cll;int main()
{int ret = cll::Add(1, 2);printf("%d", ret);return 0;
}

像上面的这个代码就没有展开域,但是他还是能正常运行。这是因为他指定了域。

缺省参数

概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。缺省值必须是常量或者全局变量。

缺省参数分类

全缺省参数

	int Add(int a = 1,int b = 2){return a + b;}

半缺省参数(只有一部分参数缺省,不是一半参数只有一部分缺省)

int Add(int a = 1,int b)
{return a + b;
}

使用

半缺省参数必须从右到左,不能跳着给。这是因为传参就是从左到右传。

int Add(int a, int b = 1, int c = 2)
{return a + b;
}
int main()
{int ret = Add(2,3);       return 0;
}

可不敢跳着传值,c++没有这样的语法,这时语法规定

int Add(int a = 1, int b = 1, int c = 2);
{return a + b;
}
int main()
{int ret = Add(1, , 3);return 0;
}

注意

声明和定义里不能都有缺省参数,声明和定义同时出现,就像如图的代码情况,缺省参数定义在声明中。

int add(int a , int b );
int main()
{int ret = add();printf("%d ", ret);
}
int add(int a = 1, int b = 2)
{return a + b;
}

这个是编译原理,当编译到调用函数,跳转到声明,声明里却没有缺省参数。就会编译错误。这是一个编译顺序问题。

函数重载

概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型 不同的问题

这里和c语言的编译原理有点不同。

c++的编译和c++编译大致一样,但是在细节上还是有区别的。

这里对上面三种类型就不多做介绍了,很简单。大家,看下面这个代码,有语法错误吗?

int add(int a = 1, int b = 2)
{return a + b;
}
int add()
{return 0;
}
int main()
{int ret = add();printf("%d ", ret);
}

有语法错误。错误是调用不明确。不是函数重载的问题。这里,是由参数的,缺省参数也是参数。

大家要对于概念明确,否则就会犯这些错误。

为什么c语言不支持重载,而c++支持呢,c++如何支持呢?

c语言在编译时会把声明当作一个承诺,当链接时回去兑现承诺。总结来就是一句话,声明是一个承诺,链接兑现承诺。

c++也是这个原理,但不同之处是c语言在编译时生成的汇编指令,是只和函数名相关。c++则是和参数个数 或 类型 或 类型顺序有关。也就是说他们两个函数名修饰规则不同。

流输入和流输出

流操作符

输入 <<

输出 >>

流输入 

cin<< ,就相当于scanf

流输出 

cout>>,就相当于printf

注意 

使用cin和cout要打开标准域std,这个域在头文件<iostream>,这两个不是函数,而是一个对象。这里先简单理解,要讲清楚比较复杂

引用

c++,提出了一种新概念,引用: 替代了实体,引用和实体共用一块内存,引用的改变会影响实体,实体的改变也会影响引用。(引用不会开辟内存,这大大提高了效率)(大对象/深拷贝类对象)

它的出现就是为了解决c语言指针的繁琐。相信刚学c语言的人会发现指针的使用很复杂。并前还很容易出现错误,尤其是野指针问题。所以我们的本贾尼老爷子(c++之父),就提出了引用。但是,在底层编译器看来他还是指针,只不过让你的使用起来变得很方便,编译器变忙了。

引用的规则

1.引用不能更改指向

2.引用必须初始化 ,int& b;这种写法是错误的

3.一个实体可以有多个引用

int a=0;

int& b=a;

引用的作用

1.做输出型参数(形参是实参的别名)(提高效率)(大对象/深拷贝类对象)

:例如swap函数

2.做返回值

:提高效率

:引用返回注意域

注意

在引用时权限不能放大,可以缩小或者平移。

大家看看这个代码,有错误吗?

int main()
{double d = 1.11;int a = d;int& b = d;}

错误是权限放大,注意截断时会产生一个临时变量,这个临时变量具有常性。所以这里的权限放大了。要注意函数返回值时和强制性转换时都会产生临时变量。

int fun()
{static int x = 0;return x;
}
int main()
{int& ret = fun(); //错误const int& ret = fun();//正确}

上面这个代码就体现了返回值时会产生临时变量,并前临时变量是具有常性的。

auto关键字

auto自动推导类型,解决使用c语言编写代码时,会遇到类型不明确的和类型过于长时的情况。所以,auto诞生。

int main()
{int a = 0;int b = a;auto c = a;auto d = 1 + 1.11;//typeid 关键字 获取类型cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;
}

注意

auto不可以做参数,因为他无法推导形参的实际类型

auto不可以用来声明数组

范围for(语法糖)

注意范围for循环范围是确定的,所以不能传指针

#include <iostream>
using namespace std;
int main()
{int arr[] = { 1,2,3,4,5 };for (auto e : arr){cout << e << " ";}
}
int main()
{int a = 0;int b = a;auto c = a;auto d = 1 + 1.11;//typeid 关键字 获取类型cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;int arr[] = { 1,2,3,4,5 };//不能修改数据 改变的是e不是数组for (auto e : arr){e *= 2;}for (auto e : arr){cout << e << " ";}cout << endl;for (auto& e : arr){e *= 2;}for (auto e : arr){cout << e << " ";}
}

他大大减少了我们遍历数组时的代码

内联函数

内联函数就是在函数的前面加上inline

内联函数的出现是为了解决c语言宏替换的麻烦,相信使用宏替换对于刚开始学习c语言的人来说,肯定会掉过很多坑,比如括号的少加。所以,我们的祖师爷也想到了这个问题。这么会这么麻烦呢?因此,内联函数诞生。

他和宏一样是替换,他不会占用内存。而是直接展开指令。所以,他没有开销,执行很快。但要注意,他也不能乱用。由于他是直接展开展开指令,所以这导致他如果过于长的时候,又被调用了很多次。那么这个代码的指令就会成倍增加。这就会导致你链接出来的可执行程序安装包会非常大。所以,一般情况下编译器会对内联函数的长度有要求。一般不超过3句。并且,使用内联函数是对编译器的一个申请,编译器很有可能会忽略掉你这个申请(代码过长时)

注意

递归可不能使用内联函数。否则你的代码指令会变得超级多,导致性能变差。

空指针NULL

c语言的NULL实际上是一个宏,它是直接被替换为0的。所以在有些使用的时候就会出现歧义。但是为了兼容c语言又不能删除,所以,c++里使用nullptr代替我们NULL。你可以把nullptr理解为是一个0强制性转化为了指针。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词