C++学习笔记一、C++初步

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变量只在当前文件可见,这样就可以将它放在头文件中,即使多次包含也不会出错。

发布了21 篇原创文章 · 获赞 63 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/u014783685/article/details/84967818