GCC
GCC编译的4个步骤
-D:编译的之后添加宏定义
//测试gcc -D选项,编译的时候指定宏定义.
#include<stdio.h>
int main(int argc, char const *argv[])
{
#ifdef DEBUG
printf("hello\n");
#else
printf("world\n");
#endif
#ifdef WEATHER
printf("sun\n");
#else
printf("rainy\n");
#endif
return 0;
}
一个宏定义使用一个-D选项,不能空格,或者逗号连着写。
-E看看预处理之后的文件啥样:
//hello.h内容
void printf_hello()
{
printf("hello\n");
}
//hello.c内容
#include<stdio.h>
#include"hello.h"
int main(void)
{
printf_hello();
return 0;
}
gcc -E hello.c -o hello.i,打开hello.i文件后可以看到把include.h和hello.h的内容都包含进来了。include.h内容太多,这里没截出来。
GCC编译参数:
-I:指定头文件所在目录位置 ,头文件和源文件在同一路径,不用指定头文件位置。
-L:指定库文件所在目录,
-l(小写L):指定库文件,因为-L只制定了库文件路径,没有指定名称,使用-l指定名称。-l和库名连着写,省略lib和.a或者.so。
-o:指定生成的文件名
-E:预处理
-S:预处理,编译,生成汇编程序
-c:预处理,编译,汇编,把前面的几步都做了。得到二进制文件。
-g:编译时添加调试语句,加了-g选项之后,可以使用gdb进行调试。加了-g后生成的可执行文件包含了调试信息,比不加文件要大一些。
-w:忽略所有警告。
-Wall:显示所有警告信息,把不重要的警告也显示出来
-On:n为0-3,编译优化,n越大优化的越多。优化的越多可能影响越大。
-D:向程序中“动态”注册宏定义
https://www.cnblogs.com/linuxprobe/p/5424353.html 关于GCC的选项讲的不错
Linux系统编程:
什么是系统调用:操作系统实现并提供给外部应用程序的编程接口,应用程序与系统之间数据的桥梁。
内核:核心程序
系统调用(内核提供的函数),服务上层应用。
Linux内核源码中其实没有write函数,有sys_write函数,write是对sys_write的浅封装,wrire代码和sys_write代码没啥区别,习惯上用write函数就说系统调用。
open:
头文件unistd.h
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回值:文件描述符,一个整数
mode:文件不存在时,指定文件的权限;文件存在时,mode失效;mode为8进制数,例如0777,0开头表示八进制。
创建文件时,文件权限还收umask影响,文件权限=mode&~umask
open常见错误:
1.打开文件不存在
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
int main(void)
{
int fd = open("hello.txt",O_RDONLY);