第三周:操作系统原理和C语言编程
CSDN学习小组–第三周
操作系统编译原理
gdb调试
gdb是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具,其中对于gdb的调试是所有在Linux操作系统下进行开发人员必备的知识
程序示例:
#只有添加 -g选项才能表示能够调试
g++ -g ./pointer1.cpp -o ./pointer1.out
gdb ./pointer1.out #指定pointer1.out为需要调试的程序
gbd l 表示显示源代码
gdb start表示开始调试
p a 表示查看 a 的值
n 表示下一步
s 表示进入函数查看
bt 查看函数栈
f 1 表示跳入栈1
q 退出调试
内存结构图
一般我们将内存分为:堆区、栈区、全局区、代码区、常量区,各个区域存放的内容:
栈区:在程序中所创建的局部变量、参数、数组、指针等,当程序执行完后,将释放所占用的该块内存。
堆区:该片区域中存放着我们手工申请的内容,如:Malloc、new所创建。
全局区:全局变量、静态变量,在我们程序执行完之后将自动释放所占用的内存。
代码区:存放着函数体的二进制代码。
常量区:包含着整形常量、字符串常量,该区域内容不能被修改。
makeFile编写
一个大型工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,能够清晰的指定,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
MakeFile文件
Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样。而且在Makefile 中可以使用系统shell所提供的任何命令来完成想要的工作,它已经成为一种工程的编译方法。
其主要结构为:
目标文件: 依赖项
命令
举例:
#设置编译器名称
CC=g++
#设置目标文件依赖
OBJ=dau.o son.o PV.o father.o main.o
father=father.cpp
dau=dau.cpp
son=son.cpp
main=main.cpp
PV=PV.cpp
#目标项:依赖项
father.o:$(father)
#编译命令
$(CC) -c $(father) -o father.o
dau.o:$(dau)
$(CC) -c $(dau) -o dau.o
son.o:$(son)
$(CC) -c $(son) -o son.o
main.o:$(main)
$(CC) -c $(main) -o main.o
PV.o:$(PV)
$(CC) -c $(PV) -o PV.o
main:$(OBJ)
$(CC) -o main $(OBJ)
clear:
rm *.o
运行makefile文件,则会生成main.o可执行文件
C语言编程
C语言程序main函数是C程序的入口函数,即程序的执行是从main函数开始,对其他函数的调动也是直接或间接地在main函数中被调用。
main函数
main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出。返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出。
其中main函数里面有三个参数:
_argc
_argv
_get_initial_narrow_environment(维护环境变量)
但其中常用的是argc和arg参数:
_argc 是个整型变量,表示命令行参数的个数(含第一个参数)
_argv是个字符指针的数组,每个原元素都是一个字符指针,指向一个字符串。这些字符串就是命令行中的每一个参数(字符串)
管道
管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,从本质上说,管道也是一种文件,但它又和一般的文件有所不同。从一个进程连接数据到另一个进程时,使用管道(pipe),通常是把一个进程的输出通过管道连接到另一个进程的输入, Linux的bash就是通过管道连接成的
程序举例
input.cpp代码:
#include <stdio.h>
int main(){
int flag=1;
int i;
int count=0;
int s=0;
while (flag)
{
scanf("%d",&i);
if( 0==i ) break;
count++;
s+=i;
}
printf("%d,%d\n",s,count);
return 0;
}
avg.cpp:
#include <stdio.h>
int main()
{
int s, n;
scanf("%d,%d", &s, &n);
float v = s / n;
printf("v=%f", v);
return 0;
}
利用管道,将input.cpp编译后的程序input.out的输出,作为avg.cpp编译后avg.out的输入,shell代码如下:
g++ ./avg.cpp -o avg.out
g++ ./input.cpp -o input.out
#使用管道
./input.out | ./avg.out
运行结果截图: