C语言是一种结构化的程序设计语言。
最初是为了开发UNIX操作系统,由丹尼斯里奇和肯汤姆逊在B语言的基础上于贝尔实验室开发出来的。C语言是一种面向过程的语言,适合处理较小规模的程序。对于复杂的,大规模的程序,需要高度的抽象,此时C语言就不再适合。因此,在C语言的基础上又增加了新的特性————类,最初,称其为“带类的C语言”。后来,又再次基础上增添了更多的新特性。所以,将其重新命名为“C++”。C++是兼容C语言的,因此C语言可以说是C++的一个子集。
C++是一种基于面向对象的程序设计语言(不是纯面向对象的语言,因为它兼容C语言)。
面向对象的三大特性:封装,继承,多态。
其中封装主要体现在两方面:
1. 将程序和数据封装在类中。其中对象是类的实例,类是对对象共有属性的抽象。以对象作为程序的基本单元,以提高程序的复用性,灵活性和扩展性。
2. C++中设置访问限定符,可以实现程序代码块内部的高内聚,代码块之间的高耦合。C++中的限定符有三种:public(公有),private(私有),protected(受保护的)。其中:
(1)public成员在类内类外可以直接访问。private成员在类内可以直接访问,但不能在类外直接访问。protected成员可以在类内部和子类的内部直接访问;
(2)在一个类内部,限定符可以使用多次,限定符的作用域为从定义处到下一个限定符定义处或类结束处;
(3)如果类中没有定义限定符,则类成员默认为私有的。在C++中,struct除了用于声明结构体外,还可以声明类,与class不同的是,struct声明的类如果没有访问限定符,则类成员默认为公有的;
C++中的数据类型:
除了包含C语言中的基本数据类型和自定义数据类型外,还新增了bool类型,class(类)类型。
C++的作用域:
除了包含C语言中的局部域和全局域外,还包含命名空间域和类域。
函数重载:是指在同一作用域内,一组函数的函数名相同,函数的参数类型或者参数个数不同,函数返回值任意(可相同可不同)
C++中支持函数重载,C语言中不支持函数重载。
C语言不支持重载:
reload.c
#include
int fun(int a,int b)
{
return a + b;
}
int fun(double a,int b)
{
return b;
}
int main()
{
fun(1,2);
fun(1.0,2);
return 0;
}
对上述代码进行编译:
由上述结果可以看出C语言中不支持函数重载。
C++支持重载:
reload.cpp
#include
using namespace std;
int fun(int a,int b)
{
return a + b;
}
//函数的重载
int fun(double a,int b)
{
return b;
}
int main()
{
cout<1,2)<cout<1.0,2)<return 0;
}
编译运行上述程序:
通过上述结果可以知道C++支持函数重载。
为什么C++支持重载,C语言不支持重载?
在LInux下对上述两个程序生成目标文件(.o文件),通过以下指令查看汇编代码:
C语言:objdump -D reloadc.o
C++:objdump -D reloadcpp.o
通过上述的结果对比,可以看出C语言中通过函数名对函数进行标识,而在C++中不仅通过函数名还有函数参数的个数和类型来对函数进行标识。当C语言中两函数的函数名相同时,即使参数不同也会被认为是重定义。但是,C++中函数名相同,只要参数不同就可以进行区分。
所以说,C++支持函数重载的原因是符号表中存放的函数名+函数个数+函数类型。C语言不支持函数重载的原因是符号表中存放的只有函数名。
缺省参数:在函数的形参列表中对参数赋予默认值的参数。
函数的参数可以分为:
全缺省参数:形参全部设定默认值
半缺省参数:对部分形参设定默认值
无缺省参数:所有形参都不设定默认值
下面通过代码来说明:
#include
using namespace std;
//无缺省
int fun(int a,int b)
{
return a + b;
}
//半缺省
int fun(int a,int b = 5)
{
return a + b;
}
**//半缺省,只能从右往左缺省,该情形错误
int fun(int a = 5,int b)
{
return a + b;
}**
//全缺省
int fun(int a = 1,int b = 5)
{
return a + b;
}
//函数的重载
//函数的重载与缺省参数的重载函数冲突时,会报错
int fun(int a)
{
return a;
}
int main()
{
//对于缺省的函数来说,如果有传实参,则使用实参,否则用默认的行参
//调用全缺省或半缺省,当两者共存时,会发生错误
//调用全缺省时:a = 1,b = 2
//调用半缺省时:a = 1,b = 5
cout<1,2)<//调用半缺省参数或只有一个int类型参数的重载函数,当二者并存时,会发生冲突
cout<1)<return 0;
}
注意:
(1)缺省参数只能从右往左连续设定
(2)对于缺省参数,若传递了实参,则用实参;若没有传递,则使用缺省参数
(3)当某些全缺省参数函数和半缺省参数函数以及函数重载发生冲突时,会报错。
(4)缺省参数不能在声明和定义中同时出现。在声明中出现了缺省参数,定义中就不能出现;在声明中没有出现缺省参数,则定义中可以出现(也可以不出现)。函数的使用按照声明的格式来调用。
(5)缺省参数的值可以使用宏和全局变量。
命字空间域相当于一个文件域。它是用来解决全局命名冲突的问题的。
命字空间的定义:以关键字namespace开头声明一个命字空间,“{}”内表示命字空间中的内容。
std:存放标准C++库中的所有组件的命字空间
如:
namespace name1
{
int a = 10;
}
namespace name2
{
int a = 20;
}
命字空间的使用方法:
(1)using namespace 名字空间名;(指定该名字空间为全局域)
(2)名字空间名::名字空间中的内容(“::”表示域作用解析符,用于指明使用哪个域)
如:
using namespace std; 表示程序中某些变量默认使用名字空间std中定义的变量。
name1::a:此时的a的值即为10,而不是20。
变量的访问规则:
1. 如果访问的变量没有指定名字空间域。
(1)如果在main中被定义为了局部变量,则遵循就近原则,访问该局部变量。
.......
int a = 20;
int main()
{
int a = 10;
cout<//输出10
}
(2)如果没有,则访问定义的全局变量。如果定义了全局变量或者using指定的全局域中都有定义该变量,则发生冲突。
namespace name1
{
int a = 10;
}
int a = 20;
using namespace name1;
int main()
{
//此时会访问冲突,因为定义了全局变量a =20
//又指定了全局域name1,name1中也有变量a
cout<
2 如果访问的变量指定了名字空间域
(1)如果显式指定了名字空间域,则根据指定的名字空间域进行查找,找不到则报错;如:
namespace name1
{
int a = 10;
}
int a = 20;
int main()
{
int a = 30
//此时会访问name1中的变量a,所以a为10;
//如果没有定义名字空间name1或者name1中没有定义变量a,则出错
cout<
(2)如果访问的变量形式”::a”,此时表示的是在全局域中访问a;对于a的访问遵循以下规则:
i)如果有全局变量,则访问全局变量a;
ii)如果没有全局变量a,则在全局域(using指定的全局域)中访问a,如果没有全局域或者全局域中没有变量a,则出错;如果using指定了多个全局域,若多个全局域中有多个a,则冲突出错;如果多个全局域中只有一个定义了a,则访问a;如:
.......
namespace name1
{
int a = 10;
}
namespace name2
{
int a = 20;
}
using namespace name1;
using namespace name2;
int a = 30;
int main()
{
cout<<::a<//此时访问全局变量a=30
}
.......
namespace name1
{
int a = 10;
}
namespace name2
{
int a = 20;
}
using namespace name1;
using namespace name2;
int main()
{
//此时访问冲突
cout<<::a<//若全局域只指定了name1或者只指定了name2,则访问相应的全局域
}
注意:
1. using可以指定多个名字空间,只要访问的变量不在多个名字空间中存在即可;
2.命字空间可以嵌套定义,访问时也要嵌套访问。
你可能感兴趣的:(C++,函数重载,缺省参数,名字空间)