1.1 C++命名空间
在函数内部使用namespace:
#include <iostream>
#include <string>
int main(){
//声明命名空间std
using namespace std;
string str;
int age;
cin>>str>>age;
cout<<str<<" age:"<<age<<endl;
return 0;
}
在 main() 函数中声明命名空间 std,它的作用范围就位于 main() 函数内部,如果在其他函数中又用到了 std,就需要重新声明:
#include <iostream>
void func(){
//必须重新声明
using namespace std;
cout<<"World!"<<endl;
}
int main(){
//声明命名空间std
using namespace std;
cout<<"Hello"<<endl;
func();
return 0;
}
如果希望在所有函数中都使用命名空间 std,可以将它声明在全局范围中:
#include <iostream>
//声明命名空间std
using namespace std;
void func(){
cout<<"World!"<<endl;
}
int main(){
cout<<"Hello"<<endl;
func();
return 0;
}
1.2 C++中的const
1.2.1 C++中的const更像编译阶段的define
const int m = 10;
int n = m;
在C语言中,编译器会先到 m 所在的内存取出一份数据,再将这份数据赋给 n;而在C++中,编译器会直接将 10 赋给 n,没有读取内存的过程,和int n = 10;的效果一样。C++ 中的常量更类似于#define命令,是一个值替换的过程,只不过#define是在预处理阶段替换,而常量是在编译阶段替换。看一个例子:
int main()
{
const int a = 10;
int b = a;
return 0;
}
将上述代码编译成汇编文件:
g++ -S -o test.S test.cpp
cat test.cpp
.file "test1.cpp"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $10, -8(%rbp)
movl $10, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4"
.section .note.GNU-stack,"",@progbits
从上面的汇编文件可以看出,a和b在栈上面分配内存,给b赋值时如下:
movl $10, -4(%rbp)
直接赋值为10,并没有从a中(-8(%rbp))中取出来。修改一下:
int main()
{
int a = 10;
int b = a;
return 0;
}
编译为汇编之后查看:
.file "test1.cpp"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $10, -8(%rbp)
movl -8(%rbp), %eax
movl %eax, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4"
.section .note.GNU-stack,"",@progbits
从上面可以看出,先将a赋值为10:
扫描二维码关注公众号,回复:
10018977 查看本文章
movl $10, -8(%rbp)
然后将a传给eax寄存器(为什么不直接赋值而要经过eax寄存器呢,这是由cpu内部结构所决定的):
movl -8(%rbp), %eax
最后将eax赋值给b(-4(%rbp)):
movl %eax, -4(%rbp)
从这一系列的赋值可以看出没有const时,b = a这句代码会将a从内存中取出来,然后再赋值给b。
1.2.2 C++中全局const变量的可见范围是当前文件
我们知道,普通全局变量的作用域是当前文件,但是在其他文件中也是可见的,使用extern声明后就可以使用,但是在C++中,全局const变量的作用域只是当前文件,例如:
main.c
#include <stdio.h>
extern int test;
int main()
{
printf("test=%d\n", test);
return 0;
}
test.c
const int test = 10;
编译运行:
gcc main.c test.c
./a.out
test=10
将main.c改为main.cpp,test.c改为test.cpp,然后用g++编译:
g++ main.cpp test.cpp
/tmp/ccmXko6D.o:在函数‘main’中:
main.cpp:(.text+0x6):对‘test’未定义的引用
collect2: ld returned 1 exit status
由上可见,C++中全局const变量只在当前文件可见,这样就可以将它放在头文件中,即使多次包含也不会出错。