前言:本文章主要介绍一些C++中的小语法。
目录
命名空间
namespace的使用
访问全局变量
namespace可以嵌套
不同文件中定义的同名的命名空间可以合并进一个命名空间,并且其中不可以有同名的变量
C++中的输入和输出
缺省参数(默认参数)
缺省参数又分为全缺省和部分缺省
既有声明又有定义的情况下
函数重载
不同作用域下的函数可以同名
调用歧义问题:
为什么C不支持函数重载,C++支持?
命名空间
为什么要有命名空间?
命名空间是解决C语言中命名重复的问题
比如,以下代码(在c++环境下运行)的情况:
#include <stdlib.h>
#include <stdio.h>int rand = 0;int main()
{printf("%d", rand);
}
在C语言中rand是一个函数名,而在该代码中定义了一个与rand函数名重名的变量。
#include <stdio.h>
int rand = 0;
int main()
{int rand = 1;printf("%d", rand);
}
以上代码的打印结果是:
为什么是1呢?
在C语言中局部优先,所以打印的是main函数中rand的值。
为什么没有报变量重定义的错呢?
因为rand这个变量是在不同的域中定义的,一个定义在局部域中,另一个定义在全局域中,所以没有命名重复。
namespace的使用
开辟一个命名空间域,可以在里面定义变量,函数,结构体等。与其他域中定义的一样的名字的变量不构成重名。
#include <stdio.h>namespace _name
{int rand = 0;
}int rand = 1;int main()
{int rand = 2;printf("%d", rand);
}
下面代码的运行结果是:
另一份代码:
#include <stdio.h>namespace _name
{int rand = 0;
}//int rand = 1;int main()
{//int rand = 2;printf("%d", rand);
}
上面的代码会报错:rand未定义
为什么呢?
编辑器的默认查找规则:
1.先去局部域中去找
2.去全局域中去找
3.但不去命名空间域中去查找。
那么如何使用命名空间中定义的变量,结构体,函数等呢?
:: 两个冒号是域作用限定符
1.全展开命名空间
#include <stdio.h>namespace _name
{int rand = 0;
}
using namespace _name;//展开命名空间//int rand = 1;int main()
{//int rand = 2;printf("%d", rand);
}
建议:在大型项目中不建议直接全展开,在平时刷题时写代码时随便用。
展开命名空间的本质:影响查找规则:
1.先去局部域中去找
2.去全局域中去找
3.但不去命名空间域中去查找。
2.指定访问
#include <stdio.h>namespace _name
{int rand = 0;
}
//using namespace _name;//int rand = 1;int main()
{//int rand = 2;//指定访问printf("%d", _name::rand);
}
3.指定某一个展开
#include <stdio.h>namespace _name
{int rand = 0;
}
//using namespace _name;
using _name::rand;//指定某一个展开//int rand = 1;int main()
{//int rand = 2;//printf("%d", _name::rand);printf("%d", rand);
}
访问全局变量
#include <stdio.h>namespace _name
{int rand = 0;
}
//using namespace _name;
using _name::rand;int rand = 1;int main()
{//int rand = 2;//printf("%d", _name::rand);printf("%d", ::rand);//访问全局域中的rand
}
namespace可以嵌套
namespace _name
{int rand = 0;namespace bit{int rand = 1;}
}
不同文件中定义的同名的命名空间可以合并进一个命名空间,并且其中不可以有同名的变量
//test.h
namespace _name
{int rand1 = 1;
}
//test.c
#include <stdio.h>
#include "test.h"
namespace _name
{int rand = 0;
}using namespace _name;int main()
{printf("%d", rand1);return 0;
}
C++中的输入和输出
#include <iostream>
using namespace std;int main()
{int i;cin >> i;//相当于scanf("%d",&i);cout << i << endl;//相当于printf("%d",i);cout << "hello world" << endl;//相当于printf("hello world\n");
}
运行结果:
代码解析:
#include<iostream>: io流,里面有定义的命名空间std
using namespace std:展开std这个命名空间,该空间中有定义的cin和cout
cout:console output 控制台输出
<<:流插入
cin: console input 控制台输入
>>: 流提取
endl:相当于“\n”,也就是换行
cin<< 可以自动识别数据的类型,相较于scanf更方便一些。
缺省参数(默认参数)
函数的全部参数或部分参数有默认值,并且调用时,可以不为有默认值的参数传参。
void f(int a = 1)//形参a有默认值,为1
{cout << a << endl;
}
以下有两份代码:
#include <iostream>
using namespace std;void f(int a = 1)
{cout << a << endl;
}int main()
{f();//不传值,那么调用时形参a为默认值1return 0;
}
#include <iostream>
using namespace std;void f(int a = 1)
{cout << a << endl;
}int main()
{f(2);//传值return 0;
}
缺省参数又分为全缺省和部分缺省
全缺省就是:全部的形参都有默认值
部分缺省: 形参从右向左顺序缺省,不能出现跳跃,所以传值的时候也不能跳跃传值
//全缺省
void f(int a = 0, int b = 1, int c = 2)
{//....
}//部分缺省
void f(int a, int b = 1, int c = 2)
{//....
}//错误示范,不是从右向左顺序缺省
void f(int a = 0, int b, int c = 2)
{//....
}
既有声明又有定义的情况下
只在定义中给形参加默认参数
//既有声明又有定义
void f(int a = 0, int b = 1, int c = 2);
void f(int a, int b, int c )
{//....
}
函数重载
函数重载的条件:同一作用域,函数名相同,形参列表不同(形参的类型不同,类型的数量不同,类型的顺序不同)
//都在全局域中定义,下面的函数参数列表都与第一个比较
void f(int a,char b)
{cout << "heihei" << endl;
}//类型顺序不同
void f(char b, int a)
{cout << "haha" << endl;
}
//数量不同
void f(int a, char b,int c)
{cout << "wuwu" << endl;
}
//类型不同
void f(double a, char b)
{cout << "lalala" << endl;
}
不同作用域下的函数可以同名
namespace tmp
{void f()//在命名空间域中定义的f函数{cout << "hello world" << endl;}}void f()//在全局域中定义的f函数
{cout << "heihei" << endl;
}
因为两个函数的作用域不同,就算将命名空间展开两个f函数仍不构成重载。
调用歧义问题:
void f(int a = 10)
{}
void f()
{}
int main()
{f();return 0;
}
即使函数重载了,也可能出现函数调用不明确的问题。
为什么C不支持函数重载,C++支持?
C中是不支持函数重载的,C++支持函数重载,
函数的地址:就是函数中有一堆需要执行的指令,而函数的地址就是需要执行的第一条指令的地址。
原因:链接时,
C是直接用函数名找函数的地址
C++是用修饰后的函数名找函数的地址
结语:希望这篇文章能够让你有所收获。