文章目录
命名空间 解决c语言命名冲突问题 1.我们自己定义的变量,函数可能和库里面重名冲突 2.但是进入公司项目组里面,做的项目通常比较大,多人协助,会导致代码中命名冲突 c语言无法解决这个问题,除非换名字 c++提出了新语法,叫命名空间, 3.命名空间里面可以包含各种东西,函数,结构体,变量
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> #include <stdlib.h> int rand = 0 ;int main () { printf ("%d" , rand); printf ("%d" , rand); return 0 ; }
namespace空间—–是一个域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> namespace b { int rand = 0 ; int a = 1 ; }int a = 0 ;int main () { printf ("%d\n" , rand); printf ("%d\n" , b::rand); int a = 1 ; printf ("%d\n" , a); printf ("%d\n" , ::a); return 0 ; }
namespace也可以嵌套包含 对嵌套包含的要用两层::
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 namespace bt { int rand = 10 ; int add (int left, int right) { return left + right; } struct node { int val; struct node * next; }; namespace n1 { int d = 2 ; } }int main () { bt::rand = 10 ; struct bt :: node nt; bt::add (1 , 2 ); bt::n1::d = 2 ; return 0 ; }
c++的输入输出 1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> int main () { cout << "hello world" << endl; return 0 ; }
1 2 3 4 5 6 7 8 9 #include <iostream> using std::cout;using std::endl;using std::cin;int main () { std::cout << "hello world" << std::endl; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std;int main () { cout << "hello world" << endl; double d = 1.2 ; int k = 12 ; cout << d <<" " <<k<< endl; cin >> k >> d; return 0 ; }
缺省 全缺省和半缺省
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 void func1 (int a = 0 ) { cout << a << endl; }void func2 (int a = 1 , int b = 2 , int c = 3 ) { cout << a << " " << b << " " << c << endl; }void func3 (int a,int b=32 ,int c=89 ) { cout << a << " " << b << " " << c << endl; }int main () { func (1 ); func1 (); func2 (); func2 (13 , 42 ); func3 (13 ); return 0 ; }struct stack { int * a; int top; int capacity; };void stackinit (struct stack*ps,int capcity=4 ) { ps->a = (int *)malloc (sizeof (int ) * capcity); ps->top = 0 ; ps->capacity = capcity; }
函数重载
函数重载:是函数的一种特殊情况,同一个函数有不同功能, 这些同名函数的形参列表(参数个数或类型或顺序)不同,用来处理实现功能类似的不同问题
函数名相同的不同函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 int add (int left, int right) { cout<<left << " " << right << endl; return left + right; }double add (double left, double right) { cout << left << " " << right << endl; return left + right; }void f () { cout << "f()" << endl; } void f (int a) { cout << "f(int a)" << endl; }void fs (int a, char b) { cout << " fs(int a, char b)" << endl; }void fs (char b,int a) { cout << " fs(char b,int a)" << endl; }void as () { cout << "ead" << endl; }void as (int a = 21 ) { cout << "as" << endl; }int main () { cout << add (3 , 2 ) << endl; cout<<add (3.3 , 8.3 )<<endl; f (); f (1 ); fs (2 , 's' ); fs ('a' , 32 ); as (); return 0 ; }
引用 引用就是给别的变量取别名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int main () { int a = 10 ; int b = a; int & c = a; int a = 20 ; int c = 30 ; int * p = &a; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int main () { int a = 0 ; int & b = a; double c = 1.1 ; int m = c; const int & r = c; cout << r<<m << endl; return 0 ; }
引用的特性 1.引用必须初始化 2.一个变量可以有多个引用 3.引用只能用一个实体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int main () { int a = 10 ; int & b = a; int k = 3 ; int & kt = k; int & ktt = k; int & m = kt; int d = 10 ; int & dt = d; int c = 20 ; dt = c; return 0 ; }
引用的应用 1.引用做函数参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void swap (int * a, int * b) { int tmp = *a; *a = *b; *b = tmp; }void swap (int & r1, int & r2) { int t = r1; r1 = r2; r2 = t; }int main () { int x = 0 , y = 1 ; swap (&x, &y); swap (x, y); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void slistpushback (slistnode*& phead, slistdate x) { slistnode* newnode = buynode (x); if (phead == NULL ) { phead = newnode; } else { slistnode* tail = phead; while (tail->next != NULL ) { tail = tail->next; } tail->next = newnode; } }
1 2 3 4 5 6 7 8 9 10 int main () { int a = 10 ; int & b = a; int * p = &a; int *& p2 = p; return 0 ; }
1 2 int * single (int * num, int numsize, int & returnsize) {}
2.引用做返回值 传值返回会有拷贝,就会有空间 传引用返回就不会有拷贝,原样返回 如果使用的变量在函数使用完之后没有销毁或者返回的空间较大,就用引用返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int dd (int a, int b) { int c = a + b; return c; }int & d (int a, int b) { int c = a + b; return c; }int & cout () { static int n = 12 ; n++; return n; }
1 2 3 4 5 6 7 8 9 10 11 int main () { int ret = dd (1 ,2 ); int r = d (1 , 2 ); cout << ret << endl; cout << r << endl; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 struct stack { int * a; int top; int capacity; };void func1 (struct stack st) { }void func (struct stack* st) { }void func (struct stack& rst) { } int main () { struct stack st; func1 (st); func (&st); func (st); return 0 ; }int & at (int i) { static int a[10 ]; return a[i]; }
常引用 用const进行修饰,在做参数的时候尽量都加一个const进行修饰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void f (const int & a) { cout << a << endl; }int main () { const int a = 10 ; const int & b = a; int c = 2 ; const int & d = c; double d = 1.11 ; int i = d; return 0 ; }
引用的优点: 引用和指针的不同点 1.引用在概念上定义一个变量的别名 (没有开空间),指针存储一个变量的地址 2.引用在定义的时候必须初始化 ,指针最好初始化 ,但是不初始化也不会报错(会变成野指针) 3.引用 在初始化时引用一个实体后,就不能再引用其他实体 ,而指针可以 在任何时候指向任何一个相同类型的实体(如我们在链表 的时候指向不同的地方) 4.没有NULL的引用,但是有NULL 的指针 5.在sizeof里面的含义不同,引用为引用类型的大小 ,但是指针是地址空间所占字节大小(32位下是4个字节 或64位里面的8个字节 ) 6.引用 自加**++是引用的那个 实体+1**,而指针 是指针指向偏移一个类型 的大小 7.访问实体方式不同 ,指针需要解引用,引用编译器里面会自己处理 8.有多级指针没有多级引用,引用比指针更加安全
extern “C” c++程序 ,调用c的库 ,再c++程序中加extern “C” 告诉c++编译器,{}里面的函数是用c的编译器编译的,链接的时候,用c的函数名规则去找,就可以链接上了,只有c++才认识extern “c”
c程序,调用c++的库,再c++库中加extern “C” c掉c++,c++的静态库就会用c的函数名修饰规则去处理以下函数,所以就不能用重载
1 2 3 4 5 6 #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C #endif
内联函数inline 我们在每次调用函数都会建立栈帧,有栈帧就会有消耗,需要建立栈帧,栈帧中要保存一些寄存器,结束后又要恢复, 可以看到这些都是有消耗的,对于频繁调用的小函数,能否优化一下呢, c语言可以用宏,来操作避免栈帧的建立
1 #define ad(x,y) ((x)+(y));
c++的实现方法inline,内联函数
有了inline就不需要去用c的宏,因为宏很复杂 ,很容易出错 inline但是展开的话,指令就会特别多 1.inline是一种以空间换时间 的做法,省去调用函数栈帧的过程,所以代码量长的函数,或者递归函数就不适合用inline,展开之后就会有特别多的指令,变得很大 所以小函数比较适合用inline 2.inline对于编译器只是一个建议 ,编译器会自动识别,递归或长的编译器会自动忽视inline 3.inline函数声名和定义不能分离 ,.h和.cpp都要加一个inline,
结论:短小 或频繁使用 的函数就定义成inline
1 2 3 4 5 6 7 8 9 10 11 12 inline int add (int x, int y) { int ret = x + y; return ret; }inline void swap (int & a, int & b) { int tmp = a; a = b; b = tmp; }