命名空间、与c的数据类型的区别、中和函数、引用

本文介绍了C++的基础知识,包括C++与C的区别、第一个C++程序的编写、名字空间的使用、数据类型差异、内存管理以及函数重载的概念和应用。强调了C++的面向对象特性,如类、继承和多态,并详细阐述了new/delete与malloc/free的不同。此外,还讨论了引用、内联函数、默认参数、静态类型转换等高级主题,帮助读者深入理解C++编程。
摘要由CSDN通过智能技术生成

一、c++介绍
由本加尼斯特劳斯特鲁普于1979年4月份至1979年10月份完成了第一个C++的预处理,为C语言增加了类机制,也就是面向对象,也就是C++
区别:
1、c++完全兼容C语言
2、支持面向对象的编程思想(封装、抽象、继承、多态)
3、支持运算符、函数重载。
4、支持泛型编程、模版。
5、支持异常处理
6、支持类型检查严格
二、第一个c++程序
1、文件扩展名:.cpp .cc .c .cxx
2、编译器:g++大多数的Linux系统需要额外安装。
sudo apt-get install g++
3、头文件: #include
#include <stdio.h> 可以继续使用
#include 建议这样使用
4、输入输出
cout<<标准输出
cin>>标准输入(不需要取地址,因为c++中是引用)
cout/cin会自动识别数据类型,不需要占位符。
printf/scanf也可以继续使用。
注意:printf和scanf 是标准库函数,cout/cin是c++标准库中类对象
5、增加了名字空间
using namespace std;
练习1:输入n个整数,计算出最大值,最小值,平均值;

#include <iostream>
using namespace std;

int main()
{
	int n = 0;
	cout << "请输入n的值";
	cin >> n;
	
	int max = 0x80000000 , min = 0x7fffffff , avg = 0 , val = 0;
	for(int i=0; i<n; i++)
	{
		cin >> val;
		if(val > max)
			max = val;
		if(val < min)
			min = val;
		avg += val/n;
	}
	cout << max << " " << min << " " << avg << endl;
}

三、名字空间
名字空间:标识符的命名范围,就是把原本的全局空间拆分,形成一个个独立的命名空间,防止全局变量的命名冲突。
匿名空间:默认为全局空间。
匿名空间中的标识符可以通过加::标识符访问,可以访问被局部变量屏蔽的全局标识符。
四、c与c++数据类型的区别
1、c++结构
1、不需要typedef,在定义结构变量时可以省略struct关键字。
2、成员可以是函数,在成员函数中可以直接访问结构成员,不需要.或->,但必须通过结构变量或结构指针才能调用成员函数。
3、有一些隐藏的成员函数(构造、析构、拷贝构造、赋值构造)。
4、可以被继承,可以设置成员的访问权限(面向对象)。
2、c++中的联合
1、不再需要typedef,可以省略union关键字。
2、成员可以势函数。。。
3、有隐藏的成员函数
3、c++中的枚举
1、不再需要typedef,可以省略enum关键字。
2、使用方法和C语言一直,但是类型检查更严格。
4、c++中的bool类型
1、c++中有真正的bool类型,bool、true、false是c++中的关键字。
2、c++中true、false是宏(0或1替换的)字节数为1、C语言中为4.
5、c++中的void*
1、在C语言中void可以与任何类型的变量互换(万能指针)。
2、在c++中void
指针就不可以和其他类型的变量互换,必须强制类型转换。
void* p;
int p1=p//错误
p=p1//正确
其他类型的指针可以给void
类型的指针赋值(为了兼容C语言)
int* ptr=(int*)malloc(4)
c++为什么修改void*?
1、安全,c++的类型检查严格
2、c++可以自动类型识别数据类型(函数重载、泛型编程),对于万能指针的需求不再强烈。
6、c++中的字符串
1、在c++中字符串被封装成了string类,也可以转换成C语言中的字符串(c_str成员函数)
2、使用时需要包含string头文件,但是已经包含着iostream头文件中,它属于std命名空间
3、常见的字符串操作已经不再需要函数,可以直接使用运算符
= strcpy
==、!=、>=、strcmp
+=strcat
size成员函数 strlen
五、c++的内存管理
1、new/delete 分配/释放堆内存的运算符
功能相当于C语言中的malloc/free
new 类型; 分配堆内存,会自动计算字节数,从堆中分配相应的内存,然后返回一个带类型的指针。

delete 指针:释放堆内存
new/delete会自动调用类型中的构造函数和析构函数,而malloc/free不会。
注意:不能与C语言中的malloc/free混用,在c++中不建议使用。
2、new[]/delete[]
new 类型[n];用于分配数组分配、释放内存,n为数组长度,会自动调用n次构造函数,所申请到的前四个字节存储着数组的长度(仅限自定义类型)
delete[] 指针;释放数组的内存,会调用n次析构函数。如果错用delete后果不确定。
注意:1、new/new[]分配内存失败时不会返回NULL指针,而是抛出异常,如果不处理,程序就会异常bad_alloc std::
2、delete/delete[] 不能重复释放,否则会产生段错误。
3、释放野指针:后果不确定,但是释放空指针是安全的的。
常考的面试题:

new/delete与malloc/free不同点:
				new/delete		malloc/free
		身份:     运算符、        函数
		参数:     类型			 字节数
		返回值     带类型的指针	   void*
		析构/构造: 自动调用	       不用
		错误:		抛异常			 返回NULL
		相同点:
				  1、管理堆内存
				  2、不能重复释放
				  3、都可以释放空指针

六、c++中和函数
1、函数重载
1、什么是函数重载
在c++中,只要函数的参数列表不同,函数名可以相同,这些同名函数构成重载关系。
2、函数重载的机制
c++代码在编译时函数的参数类型会添加到函数名中,最终生成的函数名并不相同,c++的函数再编译过程中经历了换名的过程。
注意:由于c代码在用gcc编译时不会经历换名,因此c++代码不能直接调用C编译器编译出的目标文件、库文件中函数,需要在函数声明时用extern “C”{}包括一下
3、重载和作用域
同一作用域下的同名函数才构成重载关系,不同作用域(父子)下的同名函数构成隐藏关系。
4、重载的解析过程
当调用函数时,编译器会根据实参和形参的类型匹配情况,选择一个确定的重载情况,这个过程叫做重载解析。
1、实参和形参的匹配情况有三种:找到最佳的匹配函数,编译器直接生成调用代码。
2、找不到匹配函数,编译器直接显示错误信息。
3、找不到匹配函数,实参过程类型提升(float->double等等),有一个比较合适的,将生成调用代码。
4、编译器找到多个匹配,但没有最佳的,此时会产生二义性错误。这种错误解决方案:调整实参类型,产生最优解
5、确定重载函数的步骤:
1、选择候选函数:函数调用的第一步就是确定所有的同名函数。
2、选择可行性函数:从候选函数中挑选出一个或多个函数(选择的标准是参数的个数和类型)
3、选择最佳的匹配方案:优先选择完美匹配方案,其次个数完全匹配,再其次内存字节数匹配。
6、const会影响重载的结果
参数为指针、引用类型的是否加const修饰,会影响重载的结果。
7、函数重载的优缺点:
优点:方便使用(不用取多个函数名、不用回调)
缺点:可能引起编译错误(二义性),代码段会增大。
注意:函数重载也是一种多态,在编译期间确定调用哪个版本的函数,叫编译时多态。
2、默认形参
1、在c++中可以给函数的参数变量设置默认值,当调用这种函数时,如果没有提供实参则使用默认值
2、如果只有一部分参数设置默认形参数,那么设置默认形参的参数必须连续且靠右
3、如果函数的声明和定义分开实现,只需要在声明时设置形参即可。
4、函数的默认形参时是在编译阶段确定的,因此默认形参只能设置常量、表达式、全局变量
5、默认形参会影响函数重载,提高二义性的几率。
注意:如果函数已经重载,尽量不要设置默认形参
3、内联函数
1、普通函数在编译时生成二进制指令存在代码段中,调用时生成调用指令(跳转),然后执行到调用代码位置时跳转到函数所在的代码段中执行。
2、内联函数是把函数生成的二进制指令复制到调用位置。
3、优点:提高程序的运行速度(因为不需要跳转返回)。缺点:导致可执行文件增大(冗余),是一种典型的空间换取时间的做法。
4、显示内联函数和隐式内联
显示内联:在函数前加:inine(C语言c99语法标准也可以使用)关键字。
隐式内联:结构联合、类中的内存部分成员函数这种函数会被编译器优化
注意:inline对编译只有建议权,具体是否真正内联由编译器说了算。
5、内联函数的机制与宏函数非常像,他们的区别:
内联函数是函数 宏函数是语句替换
拷贝函数二进制指令 展开宏函数代码
传参 替换
检查参数类型 不检查,任意类型都可以
有返回值 只有执行结果
6、内联适用的条件:
由于内联会造成可执行文件变大,增加内存开销(占用代码段),因此只有一次调用多次执行且简单的函数适合内联。调用次数少,且复杂的函数,内联后不能显著提高性能,不足以抵消牺牲空间带来的损失
如果函数带有递归特性,无法内联,编译器会忽略inline关键字。

七、引用
1、什么是引用:
引用就是取别名,声明一个标识符与其他对象进行绑定,相当于一个对象对应多个名字。
2、什么时候适合引用:
函数传参时适用,与指针相比,他不需要额外空间,也不用赋值,仅仅是内存与标识符的绑定,既安全又高效。
引用虽好,但并不能完全替代指针,如堆内存的时候。
3、如何使用引用
int& 标识符=变量;
4、使用引用时需要注意的问题
1、使用引用时必须初始化,不存在空引用,但是可能有“悬空”引用。
函数返回局部变量的引用,当函数执行完毕后,变量就会被销毁,此时返回的引用就是悬空引用
2、一旦引用不能更改目标
引用一旦完成定义和初始化后,标识符就与普通变量一样,他就代表引用目标,一旦引用终生不能改变目标。
3、可以引用无名的临时对象,但必须使用常引用(相当于定义了变量)
4、如果引用的目标具备const属性,那么应用也必须const。
常考面试题:c++中的指针与引用的相同点和不同点。

相同点:函数之间共享变量(获取返回值),提高传参效率。
			不同点:
				取名机制				数据类型
				不需要额外的存储空间      需要4/8字节的存储地址编号、
				不能为空				可以为空
				映射关系				指向关系
				没有二级引用			   二级指针
				不能与堆内存配合		  可以与堆内存配合
				直接访问目标		       需要解引用
				可以定义数组引用		  可以定义数组指针
				不能定义引用数组		  可以定义指针数组

八、强制类型转换
C语言中的强制类型转换在c++中也可以继续使用,但是有安全隐患,建议使用c++中的强制类型转化
1、静态类型转换
static_cast<目标类型>(源类型对象)
要求是两种类型至少有一个方向上能做隐式转换,否则报错。
2、去常类型转换
const_cast(目标类型)(源类型对象);
源类型和目标类型只有const和非const的区别,否则报错。只适用于指针和引用
const int num;
int* p=(int*)num intp=const_cast<int>(&num)
3、重解释类型
reinterpret_cast<目标类型>(源类型对象);//指针类型与整型专用
因为指针的本质是一个整数,因此任何整数类型都可以和指针类型进行转换
4、动态类型转换
dyname_cast<目标类型>(源类型);老子转儿子
1、目标类型和源类型必须是指针或引用
2、源类型和目标类型之间存在继承关系
九、操作符别名
and &&
or ||
not !
<% {
%> }
常见的笔记面试题:
C语言中的结构与C++的结构有什么区别。
new/delete与C语言的malloc/free相同点不同点。
什么是函数重载。
内联函数与宏函数的相同点和不同点。
指针与引用的相当同点和不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值