- 列表内容
using namespace std; //优化编译 没有用到的就不包含进来 // 泛型的概念 自动推理数据类型 //CPP类型检测严格 精准 属于强类型 int *p1(p2) //() 初始化 for each (int i in a) //遍历a所有的变量
#include<locale> setlocale(LC_ALL,"zh-cn"); //宽字符本地化 //C++重定向: >重写 >>追加 < <<输入 ``` ###函数模板 函数重载: 根据参数来识别 函数模板:
template
T add(T a, T b) {
return a + b;
}
“`
原生函数优先于模板函数 强行调用模板 add(1,2)
调用的时候编译 不调用的时候不编译
函数模板意义: 通用 泛型
模板接口:
template<class T> void show(T num) { cout << num << endl; } //泛型接口 任何的数据类型 任何指针 template<class T, class F> void run(T t, F f){ f(t); } run("sss", show<const char*>); //接口 严格类型
命名空间的扩展: 名称相同 同一个命名空间
命名空间的权限: using namespace data //使用命名空间 ,放在局部等同于局部变量
放在全局等同于全局变量
命名空间没有私有 ,全部变量,函数都是公有 可以访问
命名空间内部: 内层覆盖外层
// ::num 直接访问全局变量 全局变量不存在就是0 using namespace data //使用命名空间 必须在定义之后
//匿名命名空间等同于全局变量
命名空间深入:
namespace stdrun{ int numl; } namespace bb = stdrun; //别名 using stdrun::numl; //单独引用命名空间变量或者函数
一般情况下 函数实现放在命名空间之外 内部放声明
namespace stdfun { struct Date { int getsub(); }; } int stdfun::Date::getsub() //命名空间::类型::函数名 { return a - b; }
CPP没有声明与定义的差别
namespace data { int num = 100; } int main() { int num = 10; using namespace data; //局部变量覆盖命名空间 cout << num << endl; }
int num=100; void main() { int num=20; { int num=30; cout<<num<<endl; //局部覆盖 30 cout<<num<<endl; //全局覆盖 100 } }
static_extern
extern int x ; //引用外部全局变量 static int a; //作用于当前文件 static int x1 = 100; namespace{ int x1 = 90; } int main() { //同一个文件下 ::引用的还是static //跨文件下 ::一般引用是全局 cout << ::x1<< endl << endl; //100 } // ::优先级: 当前文件的stataic 再是跨文件的extern // 匿名结构体等同于全局变量 可以跨文件 // ::可以引用除匿名以外的全局变量 可屏蔽匿名
用于获取数据类型
int b; cout << typeid(b).name() << endl; //int cout << typeid(10+1.2).name() << endl; //double cout << typeid("guoshixian").name() << endl;//char const [11] int *px; char*py; if (strcmp(typeid(px).name, typeid(py).name) == 0){ cout << "=="; } else{ cout << "!="; }
#include<cstdarg> //可变参数头文件 template<class T> T add(int n, T t...) //第一个代表多少个参数 第二个代表多少类型列表 { cout << typeid(T).name() << endl; va_list arg_ptr; //开头指针 va_start(arg_ptr, n); //从arg_ptr开始读取n个 T res(0); //初始化为0 for (int i = 0; i < n; i++) { res += va_arg(arg_ptr, T);//根据数据类型 取出数据 } va_end(arg_ptr);//结束读取 return res; } int main() { cout << add(4, 1, 2, 3, 4) << endl; cout << add(5, 1, 2, 3, 4,5) << endl; cout << add(4, 1.1, 2.2, 3.3, 4.4) << endl; cin.get(); return 0; }
#include<cstdarg> //可变参数头文件 void show() //空函数结束递归 { } //参数类型不一致 个数不确定 template<typename T , typename...Args> //typename...Args可变参数 void show(T t, Args...args) { cout << t << endl; show(args...); //不能省略... } int main() { show(1,2.1,'a',"ssssss"); cin.get(); return 0; }
实习printf打印
#include<cstdarg> //可变参数头文件 void show(const char*str) //递归终止 { } //参数类型不一致 个数不确定 template<typename T, typename...Args> //typename...Args可变参数 void show(const char*str, T t, Args...args) { while (str&&*str) //指针不为空 且字符串没到末尾 { if (*str=='%'&&*(str+1)!='%') { ++str; //指针向前移动 cout << t; //打印 show(++str, args...); //继续调用 return; //递归回调时 推出while循环 } else { cout << *str++; //打印当前字符并且跳过一个字符 } } } void main() { printf("%d14555555%s%c%%%fXXXX",10,"1234",'0',1234.5); putchar('\n'); show("%d14555555%s%c%%%fXXXX", 10, "1234", '0', 1234.5); cin.get(); }
函数可以快速调用
省略参数
默认参数从右边开始,参数进栈,从右向左
不默认的参数 都在左边 默认右边
auto
自适应数据类型 自动推理
void main() { int a[5] = { 5,2,3,4,5 }; for (auto i : a) //auto i 副本 auto&i 原本 { i += 1; //并没有改变数组元素原本 改变的是a[i]的副本 cout << i << endl; //6 3 4 5 6 } cout << endl; for (auto i : a) { cout << i << endl; //5,2,3,4,5 } for (auto &i : a) //auto i 副本 auto&i 原本 { i += 1; //auto&i 改变数组元素原本 等价于 a[i]+=1; cout << i << endl; //6 3 4 5 6 } cin.get(); }
bool
非0解析为1 , 0解析为0
一个字节大小
拷贝类型
template<class T> void show(T*p) { decltype(*p) num(*p); //内存备份 } void main() { int a = 3; //decltype(a)根据一个变量表达式获取类型 (拷贝类型) decltype(a) a1[5]{ 0 }; for (auto i : a1) { cout << typeid(i).name() << " " << i << endl; } cin.get(); }
//数组初始化两种方法: //int a[5]{ 1,2,3,4,5 }; //int *p2(new int[5]{ 1,2,3,4,5 });//CPP正式写法 void main() { array<int, 10>myint1{ 1,2,3,4,5,6,7,8,9,10 }; //CPP风格数组 array<int, 10>myint2{ 1,2,3,4,5,6,7,8,9,10 }; array<int, 10>myint3{ 1,2,3,4,5,6,7,8,9,10 }; array< array<int,10> , 3 > myint{ myint1,myint2,myint3}; //CPP风格二维数组 for (auto i: myint) { for (auto j : i) { cout << j<< " "; } cout << endl; } cin.get(); }
//typedef 只能处理C语言 //typedef run runit; //c风格 不能处理c++独有命名空间 函数模板等 类 //一般情况 原则用using 取代 typedef typedef double DB; //C风格别名 using DBCPP = double; //CPP风格别名 namespace runit = run; //单独别名命名空间‘ #define INT int //宏 typedef int a[10]; //C风格别名 using intarray = int[10];//CPP风格别名 typedef int(*p)(int a, int b); //函数指针类型 using pfun= int(*)(int a, int b);//CPP风格别名 typedef int(*pa[10])(int a, int b); //函数指针数组类型 using pafun = int(*[10])(int a, int b);//CPP风格别名 //typedef三步骤 //1 定义变量: double DB; //2 加typedef: typedef double DB; //3 DB就是double //using三步骤 //1定义变量: int num; //2增加using INT=: using INT=int num; //3去掉变量: using INT=int #include<functional> namespace china{ template<class T> using t = T; template<class T> using tp = T*; //模板指针别名 template<class T> T show(T t1) { t<T> tx(t1); //使用模板别名 必须明确其数据类型 tp<int>tp1(&tx); cout << tx << " " << tp1 << endl; return T; } } using std::function; //使用命名空间一部分 using fun = std::ios::fmtflags; //命名空间的类变量或者函数别名 void main() { a a1; cin.get(); }
文章来源: C++