目录
- namespace A{ //A 是空间的名字
- int a;
- void func()
- {}
- }
(1)命名空间只能写在全局;
(2)可以嵌套;
- namespace Aspace {
- int a = 1;
- namespace B {
- int b;
- }
- }
(3)命名空间是开放的,可以随时加入新成员;
(4)命名空间可以取别名;
- namespace newSpace = oldSpace;
- newSpace:新名字
- oldSpace:旧名字
(5)分文件编写代码时,如果.h中有两个命名空间,但是里边的成员函数或变量重名时,在.cpp中实现函数时需要加上命名空间。eg:
test.h:
- #pragma once
- #include <iostream>
- using namespace std;
-
- namespace Space1
- {
- void func();
- }
-
- namespace Space2
- {
- void func();
- }
test.c:
- #include "test.h"
- void Space1 :: func() //需要在函数名之前加上命名空间的名字
- {
- cout << "func" << endl;
- }
(6)作用域运算符 ::
eg:
- #include <iostream>
- using namespace std; //标准命名空间
-
- namespace Aspace {
- int aa = 1;
- void func()
- {
- }
- namespace B {
- int b = 3;
- }
- }
-
- namespace Cspace
- {
- int c = 2 ;
- }
-
-
- int aa = 100;
-
- int main()
- {
- int aa = 10;
- cout << "aa =" << aa << endl; //就近原则,打印局部变量aa的值
- cout << "::aa =" << ::aa << endl; //如果::前边没有东西,则表示取全局的作用域,打印全局变量的aa
- cout << "Cspace::c =" << Cspace::c << endl; //::前边加上命名空间的名字则打印命名空间中对应成员的值
- cout << "Aspace::B::b =" << Aspace::B::b << endl;
-
- system("pause");
- return EXIT_SUCCESS;
- }
输出为:
- aa =10
- ::aa =100
- Cspace::c =2
- Aspace::B::b =3
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- using namespace std;
-
- namespace A {
- int a = 1;
- int b = 2;
- int c = 3;
- }
-
- void test01()
- {
- //using声明是让命名空间中某个标识符可以直接使用
- using A::a;
- cout << a << endl;
-
- int a = 50; //错误,因为using声明了某个变量,在该作用域内不能定义同名的变量
- }
-
- void test02()
- {
- //using 编译指令,让某个命名空间中的标识符都可以直接使用
- using namespace A;
- cout << a << endl;
-
- int a = 10; //这里没错,因为这里类似于命名空间中的a为全局变量,而这个a是局部变量
- }
- struct Maker
- {
- char name[64];
- int age;
- };
-
- void test()
- {
- Maker a;
- }
- struct Maker2
- {
- int a;
- void func()
- {
- cout << "func" << endl;
- }
- };
-
- void test()
- {
- Maker2 a2;
- a2.func();
- }
- void test()
- {
- char* p = (char*)malloc(64);
- }
(1)C语言中,三目运算符返回的是右值,不能被赋值;
- void test()
- {
- int a = 10;
- int b = 20;
- printf("%d",a > b ? a : b);
- //(a > b ? a : b) = 100; //err
- }
(2)C++中,三目运算符返回的是左值,是空间,可以被赋值;
- void test()
- {
- int a = 10;
- int b = 20;
- (a > b ? a : b) = 100;
- cout<<"a ="<<a<<endl;
- cout<<"b ="<<b<<endl;
- }
输出为:
- a=10;
- b=100;
| C | C++ |
|---|---|
| const修饰的变量会被存储在只读数据段,只要有定义即分配内存空间 | 全局const当声明extern或者对变量取地址时,编译器才会分配存储地址,变量存储在只读数据段 |
| 局部const存储在堆栈区,不能直接改变变量的值,可以通过指针间接修改const的值 | 只有在分配了内存后,才能通过指针间接修改const变量的值。 ① 对于const int a = 10这种,编译器会进行优化,将a替换为10,类似于#define; ② 如果用一个变量初始化const,比如const int a = b,那么也会给a分配内存; ③ 对于类对象,也会分配内存,如下代码所示。 |
| 默认为外部连接,当两个c文件中都有同样的const变量时,编译器会报重定义错误 | 默认为内部连接,不会报重定义错误。如果想让C++中的const有外部链接,必须显式声明为:extern const int a = 10; |
- const Person person; //未初始化age
- //person.age = 50; //不可修改
- Person* pPerson = (Person*)&person;
- //指针间接修改
- pPerson->age = 100;
- cout << "pPerson->age:" << pPerson->age << endl;
输出为:
pPerson->age:100
- void test02()
- {
- int a = 10;
- int& b = a; //给a的空间取别名叫b
- b = 100;
- cout << a << endl;
- }
输出为:100
而指针的写法是:
- void test02()
- {
- int a = 10;
- int* b = &a;
- *b = 100;
- }
- void func(int &b)
- {
- b = 100;
- }
-
- void test()
- {
- int a = 10;
- func(a);
- cout << "a = " << a << endl;
- }
输出为:a = 100
而C指针的写法是:
- void func(int *b)
- {
- *b = 100;
- }
-
- void test()
- {
- int a = 10;
- func(&a);
- cout << "a = " << a << endl;
- }
引用的注意:
- int main()
- {
- int arr[] = { 1,2,3 };
- //第一种方法
- typedef int(Arr)[3]; //定义数组类型
- Arr &arref = arr; //建立引用
-
- //第二种方法,直接定义引用
- int(&arref2)[3] = arr;
-
- for (int i = 0; i < 3; i++)
- {
- cout << arref[i] << endl;
- }
- }
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
- int main()
- {
- int a = 10;
- int& aRef = a; //自动转换为int* const aRef = &a;这也能说明引用为什么必须初始化
- aRef = 20; //内部发现aRef是引用,自动帮我们转换为: *aRef = 20;
- }
如下图所示:

在C语言中,如果想改变一个指针的指向,而不是它所指向的内容,则会使用二级指针,如下:
- void func(char** tmp)
- {
- char* p = (char*)malloc(64);
- memset(p, 0, 64);
- strcpy(p, "hello");
- *tmp = p;
- }
-
- void test()
- {
- char* mp = NULL;
- func(&mp);
- cout << mp << endl;
- }
改成引用的话:
- void func(char* &tmp)
- {
- char* p = (char*)malloc(64);
- memset(p, 0, 64);
- strcpy(p, "hello");
- tmp = p;
- }
-
- void test()
- {
- char* mp = NULL;
- func(mp);
- cout << mp << endl;
- }
定义格式:
const int& ref = val;
- int main()
- {
- //普通引用
- int a = 10;
- int& tmp = a;
- tmp = 20;
-
- //int &ref = 10; err,不能给字面量取别名
- const int& tmp1 = 10; //可以给const修饰的引用赋予字面量
- //编译器会把上边的代码变为:int x=10; const int &tmp1=x;
- //tmp2 = 20; err
- }
- void func(int& a, int& b)
- {
- int sum = a + b;
- cout << "sum = " << sum << endl;
- }
-
- void test()
- {
- int a = 10;
- int b = 20;
- func(a, b);
- }
如果从函数中返回一个引用,必须像从函数中返回一个指针一样对待。当函数返回时,引用关联的内存一定要存在。
- int& func()
- {
- int b = 10; //不能返回局部变量的引用
- int& p = b;
- return p;
- }
-
- int& func2()
- {
- static int b = 10;
- return b;
- }
-
- void test()
- {
- cout << "func=" << func() << endl;
- func() = 100; //如果要函数当左值,那么该函数必须返回引用
- cout << "func2()=" << func2() << endl;
- }
内联函数为了继承宏函数的效率,没有函数调用时的开销,又可以像普通函数那样,可以进行参数、返回值类型的安全检查,又可以作为成员函数。
内联函数也占用空间,但是相对于普通函数,只是省去了函数调用时的压栈、跳转、返回的开销,可以理解为内联函数是“以空间换时间”。
在普通函数前加上 inline 关键字使之成为内联函数。但是必须注意,函数体和声明结合在一起,否则编译器将它作为普通函数来对待。
inline void func(int a); //该写法没有任何效果
类内部的内联函数:
类内部定义内联函数时并不必须要加 inline,任何在类内部定义的函数自动成为内联函数。
c++内联编译会有一些限制:
- int func(int a, int b = 0) //b=0即为b的默认值
- {
- return a + b;
- }
注意:
- void func(int a, int b, int)
- {
- cout << "a+b = " << a + b << endl;
- }
-
- void func2(int a, int b, int=20)
- {
- cout << "a+b = " << a + b << endl;
- }
-
- int main()
- {
- func(10,20); //err,占位参数也是参数,必须传参数
- func(10,20,30); //ok
- func2(10,20); //ok
- func2(10,20,30); //ok
-
- return EXIT_SUCCESS;
- }
后边讲的操作符重载的后置++要用到这个。
值传递、指针传递、引用传递
- //值传递
- void swap(int a, int b)
- {
- int tmp = a;
- a = b;
- b = tmp;
- }
- //指针传递
- void swap2(int *a, int *b)
- {
- int tmp = *a;
- *a = *b;
- *b = tmp;
- }
- //引用传递
- void swap3(int &a, int &b)
- {
- int tmp = a;
- a = b;
- b = tmp;
- }
-
- void myprint(int& a, int& b)
- {
- cout << "a=" << a << "b=" << b << endl;
- }
-
- int main()
- {
- int a = 10;
- int b = 20;
- swap(a,b);
- myprint(a, b);
- swap2(&a,&b);
- myprint(a, b);
- swap3(a,b);
- myprint(a,b);
- }
上述三种交换结果,只有第一种值传递无法交换a,b的值。
- class Student
- {
- public: //公有
- void setName(string Name) //成员方法,也叫成员函数
- {
- name = Name;
- }
- void setID(int Id)
- {
- id = Id;
- }
- void myprint()
- {
- cout << "姓名:" << name << "\n学号:" << id << endl;
- }
- private: //私有权限
- string name; //成员属性
- int id;
- };
-
- int main()
- {
- Student s;
- s.setName("Paul");
- s.setID(1);
- s.myprint();
-
- system("pause");
- return EXIT_SUCCESS;
- }