C++入门:命名空间,缺省参数,函数重载讲解(细节已标识)

C++入门:命名空间,缺省参数,函数重载讲解(细节已标识),第1张

目录

1. C++关键字(C++98)

命名冲突:

2. 命名空间:namespaclass="superseo">ce关键字

2.1 命名空间定义

普通命名空间例子:

1.域作用限定符 ::

2.如何访问命名空间域内的变量:

3.不同命名空间中的同名变量如何使用:

4.命名空间的性质

细节1:这里n1是结构体,结构体已经升级成类,就可以不加struct

细节2:命名空间不影响声明周期,只是隔离了名字冲突,a还是全局变量

细节3:命名空间不能放在main函数中,只能放在全局

细节4:命名空间一般是放在头文件中

2.2 命名空间使用

1.using namespace byte ;

例子1:

例子2:using namespace byte: :cache

例子3:

例子4:

2.using namespace std;

3. C++输入&输出

(1.cin和cout讲解:

(2. C++输入输出更方便,

(3.输出支持空格 冒号分割

(4.想保留小数位数还是用c语言吧,他们输入输出可以混着用,c++也能控制但是很复杂,不建议学

4. 缺省参数/默认参数

4.1 缺省参数概念

4.2 缺省参数分类

(1.多个缺省参数:

(2.缺省参数的意义:

(3.总结:

5. 函数重载

5.1 函数重载概念


1. C++关键字(C++98)

C++总计63个关键字,C语言32个关键字

ps:下面我们只是看一下C++有多少关键字,不对关键字进行具体的讲解。后面我们学到以后再细讲。

#includ:相当于C语言里面的

using namespace std; 又是什么东西呢,接下来由此引入命名冲突和命名空间关键字 namespace

命名冲突:

命名冲突:同一个作用域不能定义同名变量 -- C语言没有很好的解决这个问题,CPP引入namespace解决这个问题

int rand = 0; int main() { printf("%d\n", rand); return 0; } 此时没问题,但是包含某些库的时候就会报错: #include //命名冲突 int rand = 0; //命名冲突 int main() { printf("%d\n", rand); return 0; }

命名冲突 -- C语言没有很好的解决这个问题,CPP引入namespace解决这个问题

2. 命名空间:namespace关键字

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作

用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字

污染,namespace关键字的出现就是针对这种问题的

2.1 命名空间定义

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

空间的成员。

普通命名空间例子:

(1)

此处打印的是函数地址,是stdlib.h中的一个创造随机值函数rand的地址

因为命名空间关键字namespace把变量rand=0关进了名叫bit的命名空间域中,隔离起来

(2)

#include

void f()
{}
int f = 0;
int main()
{
	printf("%p\n", f);
}
————————这样写就不对,改成下面这样就对了:
#include

namespace bit // 命名空间域
{
	int f = 0;
}
void f()
{}
int main()
{
	printf("%p\n", f);
}

同名变量在不同域可以存在:

局部有限,则打印1,如果找不到局部变量才打印0

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

1.域作用限定符 ::

(1)情景1 ::a 左边域是空白(左边有没有空格无所谓),默认访问全局域的a

(2)情景2 假如一个命名空间叫bit,在其中定义了变量f和rand ,想用 f 或 rand ,就要展开bit写成 bit::f 和 bit::rand

(3)情景3 假如一个命名空间叫zsh,在其中定义了一个结构体类型 ListNode ,用这个类型定义变量

namespace zsh { int a = 0; void f() { printf("void f()\n"); } struct ListNode { int val; struct ListNode* next; }; } 可以这样定义变量: zsh::ListNode* n1=NULL ; //结构体指针 struct zsh::ListNode* n1 = NULL; zsh::ListNode n2 ; //结构体变量 struct zsh::ListNode n2;

2.如何访问命名空间域内的变量:

3.不同命名空间中的同名变量如何使用:

#include #include namespace zsh { int a = 0; void f() { printf("void f()\n"); } struct ListNode { int val; struct ListNode* next; }; } namespace bit { struct ListNode { int val; struct ListNode* next; }; struct QueueNode { int val; struct QueueNode* next; }; } int main() { zsh::ListNode* n1 = NULL; bit::ListNode* n2 = NULL; return 0; }

4.命名空间的性质

1、同名的命名空间是可以同时存在的,编译器编译时会合并

2、命名空间可以嵌套

3. 命名空间中的内容,既可以定义变量,也可以定义函数,可以定义类型(结构体类型)

(这里的n1是结构体,再使用时不用带前面的类型)

细节1:这里n1是结构体,结构体已经升级成类,就可以不加struct

(左边是c++写法,右边是严格c语言写法)

细节2:命名空间不影响声明周期,只是隔离了名字冲突,a还是全局变量

细节3:命名空间不能放在main函数中,只能放在全局

细节4:命名空间一般是放在头文件中 2.2 命名空间使用

命名空间中成员该如何使用呢?比如:

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

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

使用using将命名空间中成员引入

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

1.using namespace byte ;

//这里的意思是把byte这个命名空间定义的东西放出来,使namespace byte这个命名空间无效

例子1:

前面已经有同名命名空间:

namespace byte
{
	int b = 0;

	namespace cache
	{
		struct Node
		{
			int val;
			struct Node* next;
		};
	}
}

namespace byte
{
	// a还是全局变量,命名空间不影响生命周期
	int a = 0;

	namespace data
	{
		struct Node
		{
			int val;
			struct Node* next;
		};
	}
}

如果先展开data再展开byte就错了

例子2:using namespace byte: :cache

只是展开了byte里的cache,那么可以把byte: :cache省了,原本是byte: :cache::Node n1 ,现在写成 struct Node n1 ;

但是不能只省byte ,写成struct cache: :Node n2; 就错了

例子3:

如果都放出来,data和cache中都有struct Node 这个结构体,就又重名了,就错了

最规范的还是展开一个byte

例子4:

直接using namespace bit; 会全部放出来,虽然能用f了,但是也把rand放出来了,变量rand和stdlib.h 中的函数rand又同名了,就错了

所以要用什么放什么:

单独放不用加namespace,这是语法规定

2.using namespace std;

std是c++标准库的命名空间,#include 是c++头文件

using namespace std;就是展开c++头文件的内容

如果不写这句就需要指定命名空间std里的内容 std::cout

如果下面这样放开了std,再定义cout就和库里面的某些函数冲突了,一用cout就会报错

干脆不放开,然后指定使用命名空间std里面的内容,比如std::cout或者std::endl就可以使用

只放cout,指定不指定都可以

不能连着放

3. C++输入&输出

新生婴儿会以自己独特的方式向这个崭新的世界打招呼,C++刚出来后,也算是一个新事物,

那C++是否也应该向这个美好的世界来声问候呢?我们来看下C++是如何来实现问候的。

说明:

1. 使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含< iostream >头文件以及std标准命名空间。

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件

即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文

件不带.h;旧编译器(vc 6.0)中还支持格式,后续编译器已不支持,因此推荐使用

+std的方式。

(1.cin和cout讲解:

cin和cout看成控制台,>>流提取运算符和

cin>>a ,箭头方向由cin指向a,相当于cin内数据流入a

cout

endl相当于换行

(2. C++输入输出更方便,

不需增加数据格式控制,比如:整形--%d,字符--%c

一行输入多个,一行输出多个,且不用定义格式,自动控制输出

endl相当于换行,这里用endl和\n是一样的

(3.输出支持空格 冒号分割

(4.想保留小数位数还是用c语言吧,他们输入输出可以混着用,c++也能控制但是很复杂,不建议学

(5.scanf和printf比cin和cout快一些,大量输出时有可能用,平时不考虑

4. 缺省参数/默认参数

大家知道什么是备胎吗?

C++中函数的参数也可以配备胎。

4.1 缺省参数概念

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

这里的int a=0 就是缺省参数

4.2 缺省参数分类 (1.多个缺省参数:

全缺省:缺省参数给全了

多个缺省参数,只能传完第一个再传第二个,不能直接传第二个

半缺省:缺省参数给了一部分,即缺省部分

①最少传一个(第一个),不能一个不传

②半缺省 必须从右往左缺省,并且是连续的

必须从右往左缺省,并且是连续的例子:

(2.缺省参数的意义:
struct Stack
{
	int* a;
	int size;
	int capacity;
};

void StackInit(struct Stack* ps, int n = 4)
{
	assert(ps);
	ps->a = (int*)malloc(sizeof(int)*n);
	ps->size = 0;
	ps->capacity = n;
}

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

	Stack st;
	//StackInit(&st);    //不给参数就是缺省参数,n=4
	StackInit(&st, 100); //也可以给参数,n=100

	return 0;
}
(3.总结:

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

2. 缺省参数不能在函数声明和定义中同时出现(函数声明和函数定义分离的情况)

(解释:怕你用不同的缺省参数

那该怎么给?缺省参数和声明在编译阶段处理!

声明定义都给缺省参数不行,存在歧义

声明不给定义给缺省参数不行,如果只给定义里面了,头文件#include "Queue.h" 在声明里面找不到缺省参数就报错,函数定义是在链接时连接起来的

只能声明给定义不给缺省参数,因为头文件#include "Queue.h" 展开,.cpp向上找会找到声明里面的缺省参数,)

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

4. C语言不支持(编译器不支持)

5. 函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。

比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前

者是“谁也赢不了!”,后者是“谁也赢不了!”

5.1 函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的

形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题v

A.int compare(double,double)

B.double compare(double,double)

C.double compare(double,int)

D.int compare(int,int)

只要参数列表不一样,就构成函数重载,ABC都对,D函数重载不能依靠返回值的不同来构成重载,因为调用时无法根据参数列表确定调用哪个重载函  数,故错

错误例子:

正确:

正确:
// 顺序不同
void f(int i, double d)
{
cout << "void f(int i, double d)" << endl;
}

void f(double i, int d)
{
cout << "void f(double i, int d)" << endl;
}
int main()
{
	f(1, 22.2);	
        f(22.2, 1);
}

意义:

void swap(int* p1, int* p2)
{
	int x = *p1;
	*p1 = *p2;
	*p2 = x;
}

void swap(double* p1, double* p2)
{
	double x = *p1;
	*p1 = *p2;
	*p2 = x;
}

int main()
{
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;
	swap(&a, &b);
	swap(&c, &d);

	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/791697.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存