一、Start
1.1 编译器安装
yum install gcc -y # c编译器 yum install gcc-c++ -y # c++编译器
1.2 第一个C程序
» txl.c:
#include <stdio.h> // 标准输出输入 int main() { printf(“hello”); return 0; }
1.3 编译
gcc txl.c -o txl
-o:编译并输出一个可执行文件
二、函数封装
2.1 封装 get_age() 到外部
» me.h:
int get_age(); //做一个函数申明
» me.c:
int get_age() { return 18; }
2.2 联合编译
gcc txl.c me.c -o txl
三、动态链接库
在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找、排序。为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库。
- Windows中是dynamic link library(.dll)
- Linux中是Shared Library(.so)
3.1 将 c 程序编译为 so 文件
gcc -shared me.c -o libme.so
3.2 重新联合编译
gcc –L /root/test/ -l me txl.c -o txl
-L:动态链接库的文件夹位置
-l:动态链接库的库名(去除最前面的 lib 和 .so 就是库名)
3.3 运行
虽然编译成功,但是运行依然会失败,原因是操作系统无法找到 libme.so。
其实 Linux 和 windows 一样,有个类似 system32 的系统库文件夹,各种公共类库都放于此:
- /lib:内核级
- /usr/lib:用户系统级
- /usr/lib64/:64位系统才有
所以接下来需要将 me.so 拷贝到其中一个目录中去,再更新动态库缓存:
ldconfig
四、Makefile
4.1 基本结构
在执行 make 命令后,它会自动寻找项目的 Makefile 文件来执行自动编译,该文件基本格式如下:
目标文件(target):依赖文件
<tab> gcc xxx
install:
cp xxx
如果是命令而非Makefile语法,则要在命令前打一个tab空格。
4.2 自动编译并打包 .so 文件
操作步骤如下:
- 生成 libme.so 文件;
- 利用这个 .so 文件,编译可执行程序 txl;
- 把 libme.so 拷贝到 /lib 或 /usr/lib 中;
- 执行 ldconfig 更新缓存。
» Makefile
txl:txl.c libme.so gcc -L ./ -l me txl.c -o txl libme.so:me.c gcc -shared me.c -o libme.so install: cp libme.so /usr/lib64 ldconfig
五、环境变量相关操作
环境变量分为两种:
- 本地变量(临时):可以认为是会话变量(进程级)
- 系统环境变量(PATH):系统超级依赖的一个变量
5.1 临时变量设置
myname=txl # 赋值 echo $myname # 打印 unset myname # 删除
5.2 全局变量设置
系统环境变量存放在 /etc/profile 文件中,在这里修改的内容是对所有用户起作用的,该文件是在 Bash 启动时率先运行的文件之一,而且必须要在root用户权限下才能进行操作
» /etc/prefile 末尾追加:
GOD_PATH=/god
export GOD_PATH # export用于设置环境变量,并传导到全局
然后执行 source 命令(用于在 bash 环境下读取和立即执行某文件中的命令):
source /etc/profile
5.3 用户环境变量
/home/用户/.bash_profile:该用户独有,在用户登录时读取一次
/home/用户/.bashrc:该用户独有,登录和打开新 Shell 时读取
六、文件处理相关操作
6.1 读取文件内容(按字符读)
- fopen() 打开文件,位置指针默认指向第一个字节
- fetc() 读取一个字符,指针自动往后移动
- 每个文件都有一个 EOF 标识,代表读取结束
FILE *fp = fopen(“文件名”,”r”); // 只读方式打开 char ch; // 定义一个字符变量 ch = fgetc(fp); // 读取一个字符 while(ch != EOF) { fprint(“%c”, ch); ch = fgetc(fp); } fclose(fp); // 释放
6.2 读取文件内容(按行读)
- fgets(char[], 一次读取的字节, fp):一次读取一行,读完后,指针往下移动一行
- feof() 判断当前指针是否指向最后一行
FILE *fp = fopen(“文件名”,”r”); // 只读方式打开 char chs[1024]; fgetcs(chs, 1024, fp); // 读取一行 while(!feopf(fp)) { fprint(“%s”, chs); fgets(chs, 1024, fp); } fclose(fp); // 释放
七、其他函数
7.1 C 标准库 - <string.h>
1) int strcmp(const char *str1, const char *str2)
把 str1 所指向的字符串和 str2 所指向的字符串进行比较
- 如果返回值 < 0,则表示 str1 小于 str2。
- 如果返回值 > 0,则表示 str2 小于 str1。
- 如果返回值 = 0,则表示 str1 等于 str2。
2) char *strcpy(char *dest, const char *src)
把 src 所指向的字符串复制到 dest
3) char *strcat(char *dest, const char *src)
把 src 所指向的字符串追加到 dest 所指向的字符串的结尾
4) size_t strlen(const char *str)
计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
实例:字符串相加
char *a = "tangxu"; char *b = "liang"; char c[strlen(a) + strlen(b)]; // 定义个字符数组 strcpy(c, a); // 先拷贝 a 到 c strcat(c, b); // 两者相连
7.2 C 标准库 - <stdlib.h>
1) char *getenv(const char *name)
搜索 name 所指向的环境字符串,并返回相关的值给字符串
2) int putenv(const char * string)
用来改变或增加环境变量的内容,参数string的格式为 name=value,如果该环境变量原先存在,则变量内容会依参数 string 改变,否则此参数内容会成为新的环境变量
char *result = getenv("变量名"); putenv("myname=txl");
3) int atoi(const char *str)
把参数 str 所指向的字符串转换为一个整数(类型为 int 型)