我的c++代码有什么问题? 为什么有错误?(编译环境:dev c++编译成功,无运行结果) (在线等)


这个星期已经把b站中,袁春风老师讲解的计算机系统基础(一)看完了。写这个专栏已经差不多一个月了。也就是说,花费了一个月的时间把计算机系统基础(一)视频看完了。但是,最近我又陷进了“看这些基础知识有什么用?”、“这个知识,了解一下就够了,脑海里知道有这个知识”。就是这些想法,让我对一些知识浅尝即止,没法深入的去学习。学习后面链接的过程的视频,也有点囫囵吞枣。所以我还是下定决心,创建Linux的虚拟机,踏踏实实敲好每条指令。回想起建立专栏的初衷,不就是为了记录知识,将知识系统化。其实,在写专栏的时候,我也发现写文章,其实就是一个思考的过程。因为在这个过程中,你需要把知识分享给其他人,你就必须详细去理解知识。这时候,自己就会产生一些问题,就会去思考为什么会这样?还是要不断砥砺自己。不忘初心,继续前行。
在这篇中,链接是主菜。在上主菜之前,我们还是先来尝一下开胃菜——编译的过程。在Linux中,gcc命令实际上是具体程序的包装命令,用户通过gcc命令来使用具体的 预处理程序cpp、编译程序cc1和汇编程序as等。预处理(生成.i预处理文本文件)命令-$gcc -E hello.c -o hello.i -$cpp helloc.c > hello.i处理源文件中以“#”开头的预编译指令,包括:-展开定义的宏-处理所有条件预编译指令,如#if,#ifdef,#endif等-插入头文件到#include处-删除所有的注释"//"和"/**/"-添加行号和文件标识,以便编译时编译器产生调试用的行号信息-保留所有#pragma编译指令(编译器需要使用)编译(生成.s文本文件)命令-$gcc -s hello.i -o hello.s进行词法分析、语法分析、语义分析并优化,生成汇编代码文件。汇编(生成.o可重定向目标文件,不可读二进制代码)命令-$gcc -c hello.s -o hello.o -$as -c hello.s -o hello.o
ElF头
ELF头:文件类型、机器类型、节头表的表项大小以及表项个数。.text节:编译后的汇编代码.rodata节:只读数据,如printf格式串、switch跳转表等。.data节:已初始化的全局变量,局部静态变量。.bss节:未初始化的全局变量,局部静态变量。仅是占位符,不占据任务实际磁盘空间。.symtab节:符号表,存放函数名和全局变量信息(不包括局部变量)。.rel.text节:代码段的重定位信息.rel.data节:数据段的重定位信息.debug节:调试用的符号表.strtab节:包含symtab和debug节中符号及节名。?.line节:?Section Header table(节头表):每个节的节名、偏移和大小看完,还是不知道.strtab 和 .line 有什么具体作用?先留一个疑问。后续再回来看看。链接(将多个目标文件,生成一个可执行目标文件)命令-$gcc -static -o myproc main.o test.o -$ld -static ...可执行目标文件,与可重定位目标文件一样,是一个不可读的二进制代码文件。可通过工具逆向转化为文本文件objdump -d test.o。以下是两个目标文件的逆向转化后的比较。链接操作的步骤:1.符号解析程序中有定义和引用的符号(包括变量名,函数名),存放在符号表(.symtab)。符号表是一个结构数组,包含符号名、长度和位置等信息。编译器将符号的引用存放在重定位节(.rel.text和.rel.data)。链接器将每个符号的引用都与一个确定的符号定义建立关联。
重定位信息
2.重定位将多个代码段和数据段分别合并为一个单独的代码段和数据段,计算每个定义的符号在虚拟地址空间的绝对地址。将可执行文件中的符号引用处修改为重定位后的地址信息。符号类型:全局符号(Global symbols):由模块m定义并能被其他模块引用的符号。(指不带static的全局变量)外部符号(External symbols):由其他模块定义,并被模型m引用的全局符号。局部符号(Local symbols):仅由模块m定义和引用的本地符号。例如,在模型m中定义的static函数和变量。在开发过程中,容易遇到的符号重复定义的问题。比如://a.cpp文件
//b.cpp文件
两个文件在合并数据段时,就会发生链接错误。因为两个文件重复定义了变量名,在链接过程中,无法用同一符号,表示两个变量。如果,是一个强定义,一个弱定义编译通过。所谓,强定义就是定义的同时赋值,而弱定义只定义。所以,养成良好的编程习惯。尽量使用本地变量(static),模块内引用不太会出错全局变量要赋初值,使成为强符号,易查出链接错误外部全局变量使用extern,以示其引用其他模块
在链接后,函数p1修改yz的值,会重定位到main.c中定义的yz的地址
在编译阶段,两个文件是分开编译的,所以p1.c中把d当作一个double来处理了,生成相对应的汇编代码。在对d赋值时,设计上就会修改main.c中定义的在数据段中的d,同时会覆盖x。
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐

我要回帖

更多关于 dev c++编译成功,无运行结果 的文章

 

随机推荐