在C语言中,全局变量是不能重名的,在 C++ 复杂项目开发中不可避免遇到同名问题,这时就引入了命名空间,允许变量同名。
在C++使用命名空间将标识符名本地化,本地化内名字不可重复,本地以外可以重复,有点类似不同函数内同名的变量,只是命名空间内变量可以全局化。
简单说就是把相同标识符名放到不空间里关起来!虽然名字相同,当本质不同。
命名空间使用 namespace 关键字,:: 是作用域。例如:下 v 变量是不同空间内的。
#include
namespace N1
{
int v = 100;
}
namespace N2
{
int v = 20;
}
int main(void)
{
printf("%d\n", N1::v);
printf("%d\n", N2::v);
return 0;
}
结果:
100
20
在上例访问命名空间中的变量不能直接访问,要用 命名空间名 + 作用域(::) 的方式。
用 using 关键字可以将 命名空间内 的变量释放出来,可以直接访问。
#include
namespace N1
{
int v = 100;
}
namespace N2
{
int v = 20;
}
using namespace N1; //
int main(void)
{
printf("%d\n", v);
printf("%d\n", N2::v);
return 0;
}
结果:
100
20
注意:不能把两个同名变量的命名空间都释放,否则也出现同名冲突,同空间内作用域内不能出现同名。下例子就错误了
#include
namespace N1
{
int v = 100;
}
namespace N2
{
int v = 20;
}
using namespace N1;
using namespace N2;
int main(void)
{
printf("%d\n", v);
printf("%d\n", N2::v);
return 0;
}
结果:编译出错
C | C++ | |
---|---|---|
输入 | scanf | cin |
输出 | printf | cout |
C++相比C语言输入输出省略了格式化的输出。简单了一些。
#include //头文件,C++11可以不用加.h、*hxx
using namespace std; //命名空间声明
int main(void)
{
int a = 0 ;
int b = 1 ;
int c = 2 ;
cout << a; //正确
cout << a << endl;; //正确,换行
std::cout << b; //正确
std::cout << b << std::endl; //正确,换行
std::cout << "以上格式都对" << std::endl; //正确
std::cin >> a >> b >> c; //连续输入
std::cout << a << std::endl << b << std::endl << c << std::endl; //连续输出
return 0;
}
理解记忆:
cin >> a; //从键盘中输入到 a ; 或控制台流向 a
cout << a; //从 a 输出到显示器; 或a流向显示台
C++中调用函数可以不用传参,不传参函数则采用默认参数,若没有默认参数就必需传参
#include
using namespace std; //命名空间声明
void test1(int a = 1, int b = 2) //全缺省参数。意思可以不用全传参
{
cout << a << ' ';
cout << b << endl;
}
void test2(int a, int b = 2) //半缺省参数。意思b可以不用传参, 但a必需传参
{
cout << a << ' ';
cout << b << endl;
}
/*
void test3(int a = 1, int b) //这种 半缺省参数 是不对的。
{
cout << a << ' ';
cout << b << endl;
}
*/
int main(void)
{
test1(); //形参默认值
test1(9); //形参a传参, 形参b默认值
test1(9, 10); //形参a, b 传参
//test2(); //错误
test2(19); //形参a传参, 形参b默认值
test2(19, 100); //形参a, b 传参
return 0;
}
结果:
1 2
9 2
9 10
19 2
19 100
C++中允许函数重名,重名的函数叫重载函数。
C语言中则不允许,是因为编译器处理方式不同造成的,C/C++生成可执行代码过程:预处理、编译、汇编,链接
在linux 中 gcc编译C语言; g++编译C++语言。
C++中,同名函数的条件:
1、函数的参数个数不同。
2、函数的参数类型不同或者参数类型顺序不同,
#include
using namespace std; //命名空间声明
void test(int a, int b)
{
cout << a << ' ';
cout << b << endl;
}
void test(int b)
{
cout << b << endl;
}
int main(void)
{
test(1, 2);
test(2);
return 0;
}
总结:重载函数虽然名字可以相同,但参数必需要不同,通过参数不同来区分,本质来说函数并没有全部相同,仅名字相同。
引用其实就是取别名,内存空间地址还是同一块,取不同名字。有点像人取了多个名字一样。
引用类似指针,但不同,引用是取别名,是同一块空间;指针是指向同一块空间。仔细品有不同。
#include
using namespace std; //命名空间声明
int main(void)
{
int a = 1;
int &b = a; //b引用a
cout << a << endl;
cout << b << endl;
return 0;
}
#include
using namespace std; //命名空间声明
int main(void)
{
int a = 1;
const int &b = a; //b引用a, b是只读的,权限被缩小
cout << a << endl;
cout << b << endl;
return 0;
}
int main(void)
{
const int a = 1; //a是只读
int &b = a; //b引用a, b是可读写,权限被放大;这是错误的,权限不能被放大,只能缩小
return 0;
}
int main(void)
{
int &a = 1; //错误
const int &a = 1; //正确
return 0;
}
int main(void)
{
double a = 3.14;
int b = 1; //隐式转换
/*如果用int引用double,引用不是原来地址的那个double,
而是double转化为int时的那个中间变量,因为它具有常性*/
int &c= a; //错误
const int &c= a; //正确
return 0;
}
#include
using namespace std; //命名空间声明
int& test(int a)
{
int b = a + 1; //计算结果存储临时空间 b 中
return b;
}
int main(void)
{
int& c = test(2); //这种方式返回值就少了一次赋值动作
cout << c << endl;
return 0;
}
内敛函数 类同 C 语言中用宏定义 一段代码,这样函数调用的使用就不用产生压栈出栈,相当把函数内容替代展开过去。
内联函数 使用 inline 修饰。
#include
using namespace std; //命名空间声明
inline int test(int a) //内敛函数
{
int b = a + 1; //计算结果存储临时空间 b 中
return b;
}
int main(void)
{
int c = test(2); //相当把函数内容拷贝过来,不用调用。
cout << c << endl;
return 0;
}
内敛函数 不适合 循环、递归中,深度太深,展开空间太大。
内敛函数是 空间换时间 的做法。
##8 基于范围的for循环
#include
using namespace std; //命名空间声明
int main(void)
{
int ary[] = {1, 2, 3, 4};
for(int i=0; i<sizeof(ary)/sizeof(int); i++) //C for循环
{
cout << ary[i] <<" ";
}
cout <<endl;
for(auto x : ary) //C++ 基于范围的for循环
{
cout << x <<" ";
}
return 0;
}
在C中对不用指针初始化为NULL,其实NULL就是0,但在重载函数中就会出错,例如下例。
C++中指针赋值空指针则用nullptr。
#include
using namespace std; //命名空间声明
void test(int a)
{
cout << 1 << endl;
}
void test(int* a)
{
cout << 2 << endl;
}
int main(void)
{
test(0);
test(NULL); //NULL是0,就无法分辨是那个函数了
test(nullptr);
return 0;
}
早期是修饰符,意思为自由的,在C++11重新被定义了。
在C++11中是类型说明符,auto声明的变量必须由编译器推导获得。
#include
#include
using namespace std; //命名空间声明
int main(void)
{
int a = 1;
auto b = a; //自动推导变量类型
cout << typeid(b).name() << endl;
return 0;
}