小言_互联网的博客

一篇文章带你初识C++

189人阅读  评论(0)

1.命名空间

关键字:namespace

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作 用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字
污染,namespace关键字的出现就是针对这种问题的。

命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名 空间的成员。

//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
   
 // 命名空间中的内容,既可以定义变量,也可以定义函数
 	int a;
	 int Add(int left, int right)
 	{
   
		 return left + right;
 	}
}
//2. 命名空间可以嵌套
namespace N2
{
   
 	int a;
 	int b;
 	int Add(int left, int right)
 	{
   
 		return left + right;
 	}
 
 namespace N3
 {
   
	int c;
 	int d;
 	int Sub(int left, int right)
 	{
   
 		return left - right;
 	}
 	
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
   
 	int Mul(int left, int right)
  	{
   
 		return left * right;
 	}
}

命名空间的使用

命名空间的使用有三种方式:
加命名空间名称及作用域限定符
使用using将命名空间中成员引入
使用using namespace

//1.使用命名空间名称及作用域限定符
int main()
{
   
	 printf("%d\n", N::a);
 	 return 0; 
}
//2.使用using将命名空间中成员引入
using N::b;
int main()
{
   
 	printf("%d\n", N::a);
 	printf("%d\n", b);
 	return 0; 
}
//3.使用using namespace 
using namespce N;
int main()
{
    
	printf("%d\n", N::a); 
	printf("%d\n", b); 
	Add(10, 20);
    return 0;
 }

在C++中我们开头总是写using namespace std; 很多人压根不知道这句话的意思,这里的std就是命名空间,当然这句话的意思就是使用标准命名空间

2.函数缺省

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

缺省参数分类:
全缺省参数
半缺省参数

//1.全缺省参数
void TestFunc(int a = 10, int b = 20, int c = 30)
{
   
 	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
}
//2.半缺省参数
void TestFunc(int a, int b = 10, int c = 20)
{
   
	 cout<<"a = "<<a<<endl;
	 cout<<"b = "<<b<<endl;
 	cout<<"c = "<<c<<endl;
 }

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
  3. 缺省值必须是常量或者全局变量
  4. C语言不支持(编译器不支持)

3 .函数重载

函数重载:即在C++中容许有同名的函数 函数重载的条件:函数的参数类型不同,返回值不同 注:函数的返回值不能构成函数重载的条件

#include<iostream>
using namespace std;
void Print(int a)
{
   
	cout << a << endl;
}
void Print(double a)
{
   
	cout << a << endl;
}
int main()
{
   
	Print(1.0);
	Print(1);
	return 0;
}

如上述例子所述,我们要实现两个自定义打印函数,一个打印整数,一个打印浮点数,两个函数列表的参数类型不同
而函数名却相同,但是我们在编译时却不会报错,这就是函数重载,让我们实现了打印两个不同类型打印函数
而在C语言中我们就要起两个函数名来实现这件事,如Print_int,Print_double
那么为什么会出现函数重载这件事呢,这就要从编译链接的过程开始说起:
1.预处理:头文件的展开+宏替换+去掉注释+条件编译
2.编译:检查语法,将代码转化成汇编代码
3.汇编:汇编代码转化为二进制的机器码
4.链接:将所有文件连接在一起,生成可执行程序 而C++在编译过程中有函数名修饰规则:函数的返回值+函数名+函数参数类型,这样每个函数就能够进行独立识别,既不会产生命名冲突,如下所示:


#include<iostream>
void  print(int a)
{
   
	cout << a << endl;
}
void print(string str)
{
   
	cout << str << endl;
}
using namespace std;
int main()
{
   
	print(1);
	print("hello  world");
}

将上述代码在Linux下利用g++编译之后,我们会产生下述结果:

这里我们会发现void print(int a)在这里变成了_Z5printi

而void print(string str)在这里变成了_Z5printSs
我们来对比一下:
从void print(inta)—>_Z5printi;
而void printf(string str)—>_Z5printSs;
前面_Z5我们也许不认识,但是看到print我们应该能够联想到这是我们定义的函数名,那么后面的i我们也就可以去联想到知识函数的参数类型,i代表int,Ss代表string,那么我们就可以大胆的猜测_Z5就是前面的函数的返回值类型,这样每一个函数在编译之后:就会形成:
函数返回值+函数名+参数列表类型
这将成为为函数唯一修饰,这样看似两个相同的函数就会被特定的区别开来,也就出现了函数重载现象
而在C语言中,我们将下面代码在Linux gcc下编译之后:

#include<iostream>
using namespace std;
int Ad(int a, int b)
{
   
	return a + b;
}
void func(int a,  double b, int* p)
{
   

}
int main()
{
   

	return 0;
}

并没有出现像上面C++中那样有函数名修饰规则,而是直接就写了函数名,这样要是出现两个相同的函数名他就无法进行区分,则会报错,这也就解释了为什么C++支持函数重载,而C语言不支持函数重载,总而言之就是二者的函数名修饰规则不同

2.引用

简单来说就是给一个变量起别名 引用不是重新写一个变量,而是给一个变量起别名,他和他引用的变量共同访问一块内存空间
基本语法:数据类型 &别名 = 原名
例如 int a=10;
int &b=a;

如上图所示,我们给变量a起别名为b,此时变量a和b就能共同访问这块内存空间,此时我们改变b的值为100,我们会发现a的值也会变为100,这就是最基础的引用
.引用的注意事项: 引用必须初始化 引用在初始化后不可以改变

引用的作用

1.引用做函数参数
作用:函数传参时,可以利用引用的技术让形参修饰实参
实例:

#include<iostream>
using namespace std;
//交换函数
//1.址传递
void swap1(int a, int b)
{
   
	int temp = a;
	a = b;
	b = temp;
	cout << "swap1 a=" << a << endl;
	cout << "swap2 b=" << b << endl;
}
//2.地址传递
void swap2(int* a, int* b)
{
   
	int temp = *a;
	*a = *b;
	*b = temp;
}
//3.引用传递
void swap3(int& a, int& b)
{
   
	int temp = a;
	a = b;
	b = temp;
}
int main()
{
   
	int a = 10;
	int b = 20;
	//swap1(a, b);//值传递形参不会改变实参
	//swap2(&a, &b);//地址传递形参会改变实参
	swap3(a, b);//引用传递形参也会修饰实参
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	system("pause");
	return 0;
}
总结:引用的效果和地址传递效果是一样的,引用语法更加清楚简单

2.引用做函数返回值
作用:引用是可以做函数返回值存在的
注意:不要返回局部变量引用
实例:

#include<iostream>
using namespace std;
//引用做函数返回值
//1.不要返回局部变量的引用
int& test01()
{
   
	int a = 10;//局部变量在栈区中
	return a;
}
//2.函数的调用可以作为左值
int& test02()
{
   
	static int a = 10;//全局变量程序运行完后由系统自动释放
	return a;
}
int main()
{
   
	int &ret=test01();
	cout << ret << endl;//第一次正确,编译器做了保留,
	cout << ret << endl;//第二次错误,因为a的内存已经释放
	int& ref = test02();
	cout << "ref=" << ref << endl;
	cout << "ref=" << ref << endl;
	test02() = 1000;///如果函数返回值是引用,这个函数调用可以作为左值
	cout << "ref=" << ref << endl;
	system("pause");
	return 0;
}

引用的本质

本质:引用的本质在c++内部实现是一个常量指针
int&a=b==>int* contst a=&b;
指针指向不可以修改,但是其值可以修改
PS:引用一旦初始化就不可以发生变化

#include<iostream>
using namespace std;
void test(int& a)
{
   
	a = 100;
}
int main()
{
   
	int a = 10;
	int& b = a;//相当于int* const b=&a;
	b = 20;//相当于*b=20
	cout << "a=" << a<<endl;
	cout << "b=" << b << endl;
	test(a);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	system("pause");
	return 0;
}

以上就是本篇文章所有内容,希望各位看官能够喜欢,如果有错误的地方,还请多多斧正,感谢大家支持


转载:https://blog.csdn.net/weixin_51476766/article/details/117042707
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场