C++的命名空间、输入&输出、缺省参数、重载、引用和内联函数

命名空间

在C++中,命名空间(Namespace)是一种用于组织代码的机制,以防止名称冲突。命名空间允许组织代码中的符号(如类名、变量名、函数名等),使得同一符号在不同命名空间中可以代表不同的实体。这对于管理大型项目中的名称非常有用,特别是在涉及多个库时。

命名空间和作用域:

  • 命名空间(Namespace): 在编程中,特别是在像C++这样的语言中,命名空间是用于区分不同代码段中相同名称的一种方法。它们帮助避免命名冲突,并且可以组织代码,使其更加模块化。
  • 作用域(Scope): 在编程中,作用域是一个变量或函数可以被访问的区域。在一个作用域内声明的变量只能在该作用域内被访问。作用域可以是局部的(如在函数内部)或全局的。

定义命名空间的几种方式

  定义命名空间

namespace 名称 {
    // 代码,例如类、函数、变量等定义
}

 命名空间的几种主要使用方式

         加命名空间及作用限定符(指定命名空间访问)

int main()
{
    printf("%d\n", N::a);
    return 0;
}

         使用using部分展开

using N::b
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;
}

        全局展开

using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

 命名空间的几个特质

 命名空间的跨文件

输入&输出

在C++中,cincout 是iostream库中定义的两个对象,分别用于标准输入和标准输出。cin 通常与提取运算符 >> 结合使用来从标准输入(如键盘)读取数据,而 cout 通常与插入运算符 << 结合使用来向标准输出(如屏幕)写入数据。

#include <iostream>

int main() {
    int number;
    std::cout << "Please enter a number: "; // 提示用户输入一个数字
    std::cin >> number;                      // 从标准输入读取一个整数

    std::cout << "You entered: " << number;  // 输出用户输入的数字
    return 0;
}

 << 运算符用于将数据“插入”到输出流中,而 >> 运算符用于从输入流中“提取”数据。

你可以将多个 << 或者 >> 运算符链接起来,以便在单个语句中进行多次插入或提取操作。

例如,从用户连续读取两个数字:

int a, b;
std::cin >> a >> b;

 或者连续打印多个值:

std::cout << "First number: " << a << ", Second number: " << b;

缺省参数

在编程中,缺省参数(又称默认参数)是函数或方法参数列表中的一种特性,允许在定义函数时为一个或多个参数指定一个默认值。如果在调用函数时没有为这些参数提供值,就会使用这些默认值。这允许在不影响现有代码调用的情况下增加新的参数,也使得函数调用更加灵活。

using namespace i;
void Func(int a = 0)
{
	cout << a << endl;
}

int main()
{

	Func();//这里的的a并没有输入变量,但是它还是会直接等于0
	Func(10);
	return 0;
}

全缺省 

其中所有的参数都有默认值

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);
	Func(1, 2);
	Func(1, 2,3);


	return 0;
}

半缺省

 其中一些参数有默认值,而其他一些则没有。这意味着对于有默认值的参数,调用函数时可以不提供实际的参数值,这些参数会自动使用定义函数时指定的默认值。

//半缺省,(缺省值只能从右往左给,必须连续给
//不能定义和声明都给一个缺省参数
//也不能只给定义
//只能声明给
void Func(int a , int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;

}

int main()
{
	Func(1);
	Func(1, 2);
	Func(1, 2, 3);


	return 0;
}

 注意事项

1. 半缺省参数必须从右往左依次来给,不能隔着给

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

3.缺省值必须是常量或者是全局变量

重载

函数重载是一种编程特性,它允许同一个程序中存在多个同名函数,但这些函数的参数列表必须不同。参数列表的不同可以是参数的数量不同,参数的类型不同,或者参数的顺序不同(如果参数类型不全相同)

 //1、参数类型不同 (类型不同,个数不同)返回值可同也可以不同
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}

 函数重载的规则:

  1. 重载的函数必须在参数类型、数量或顺序上有所不同。
  2. 不能仅通过返回类型的不同来重载函数。
  3. 当调用一个重载的函数时,编译器会根据传递的参数类型来确定使用哪个函数。

名字修饰规则 

函数的签名包括函数名和参数列表(包括参数的类型、数量、顺序)。每个重载函数都必须有一个独一无二的签名。请注意,函数的返回类型不是函数签名的一部分,因此不能仅通过返回类型来区分重载的函数。

Linux的名字修饰规则:函数名加上参数类型的前缀

windows的名字修饰规则 

引用

在C++中,引用是一种复合类型,它是某个已存在变量的别名。引用的工作方式类似于指针,但有几个关键区别:引用一旦被初始化为某个变量的引用后,就不能再指向另一个变量,而指针可以在任何时候指向另一个地址。此外,引用本身不是一个可以操作的独立对象,它没有自己的内存地址,而指针是一个实际的对象,有自己的内存地址。

引用在声明时必须被初始化,并且不能为null。引用通常用于函数参数传递,使得函数可以直接操作实参变量,而不仅仅是操作其副本。这样不仅可以提高效率(特别是对于大型对象的操作),还可以允许函数修改其参数的值。

引用的使用场合:

  1. 函数传参:使用引用作为函数参数可以避免拷贝大型对象,同时也可以让函数修改传入对象的值。

  2. 函数返回值:函数可以返回一个对象的引用,这样可以避免返回值时的对象拷贝。但要小心不要返回局部对象的引用,因为局部对象在函数结束时会被销毁。

  3. 操作符重载:在重载赋值操作符=、下标操作符[]、解引用操作符*和箭头操作符->等时,经常需要返回引用类型。

函数传参

引用就是这个变量的别名,所以当这个数被传进了swap这个函数中的时候,它拥有了一个新名字,left。 而传地址,是在函数中创建一个指针,指向的地址是变量的地址,这个时候解引用指针就可以找到这个地址进行更改了

区别就是引用不占用空间,和原变量使用一块新的地址。而指针在创建的时候,会请求一块空间存放指针

函数返回值

 在左侧的流程图中:

  • 主要描述了main函数调用Count函数的流程。
  • Count函数内部有一个局部静态变量n,它的值在函数调用之间是持久的。
  • Count函数返回n的引用给main函数。
  • 流程图指出这种返回引用的方式是不安全的,因为它可能导致返回的引用指向一个不再有效的局部静态变量(尽管在这种情况下,由于n是静态的,它在程序的整个运行期间都是有效的)。

操作符重载

#define N 10 
struct Array
{
	int& at(int i)
	{
		assert(i < N);
		return a[i];
	}
	int& operator[](int i)
	{
		assert(i < N);
		return a[i];
	}
	int a[N];
	int size;
}AY;
//临时变量具有常性不能修改
//1. 减少拷贝
//2. 调用者可以修改返回对象


int main()
{
	Array ay;
	for (int i = 0; i < N; ++i)
	{
		//ay.at(i) = 0;
		//ay.operator[](i) = 0;
		ay[i] = 0;
	}
	for (int i = 0; i < N; ++i)
	{
		cout << ay[i] << " ";
	}
	cout << endl;

	return 0;
}

 引用做返回值才能使用这些,因为这些直接做成返回值,属于是一个临时变量,但是临时变量具有常性,不能改变 ,所以不能作为左边的赋值,但是如果是引用的话,就可以代表这个数的别名,可以进行操作

关于类型转换生成临时变量

在C++中,当发生隐式类型转换(也称为类型提升)时,如果是从一个非const类型转换到另一个类型并试图将结果绑定到一个const引用上,编译器会创建一个临时变量来存放转换后的值。这个临时变量是const的,意味着你不能通过引用来修改它的值。

这样做的原因是确保类型安全和对象的不变性。当你将一个临时变量的引用绑定到一个const引用上时,编译器保证你不能修改这个临时变量,因为临时变量的生命周期很短,只在表达式的持续期间存在。如果允许修改,那么修改可能会在没有任何对应变量存在的情况下发生,这会导致不可预测的行为。

//常引用
int main()
{
	//权限不能放大
	const int a = 10;
	int b = a;
	//int& b = a;
	const int& b = a;

	//权限可以缩小
	int c = 20;
	const int& d = c;

	const int& e = 10;
	//int& e = 10;//不可以,权限放大了

	int i = 1;
	double j = i;

	const double& rj = i;

	//指针的权限也不能放大,可以缩小
	const int* p1 = NULL;
	//int* p2 = p1;

	//权限保持
	const int* p1 = NULL;
	const int* p2 = p1;
	return 0;
}

一些底层关于引用和指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值