env 查看所有环境变量
-------------------------------------
预处理:在编译之前通过预处理程序 gcc -E,预处理只是简单的替换,不作C语法检测,只检测宏的语法.
预处理以 # 号开头
宏 定义 #define 名字 宏体
#define名字(参数) 宏体
宏名字都用大写字母
宏不占内存;a
用宏来替换函数;
#define P(fmt,arr...) printf(fmt,##arg)
#defineERROR(fmt,arr...) printf(fmt, ##arg) //...表示参数列表,arr是参数列表名字
#defineINFO(...) printf(__VA_ARGS__)
宏定义函数
#define SWAP(a, b) { int temp = a;
a = b;
b = temp; }
其中 是宏换行号,表示后面的内容与当前行是同行,后面不能有空格,{}只是把宏括起来,替换后可以看成是一个代码段.用do{ ; ; ; }while(0) 括起来,则可看成一条语句
-------------------------------------------
条件编译 //若#if #elif后面值为0,则预处理时会把不代码擦掉,注释也会把注释的代码擦掉
#if
#elif
#else
#endif
#if与#elif 后面可用逻辑运算式
#ifndef 宏名 //定义了宏名才会去执行下面的语句 gcc-D 宏名 文件名 表示在编译时定义宏名,使下面的语句得以执行.
commad;
#endif
#ifdef
command
#endif
-----------------------------------------
头文件:
.h结尾,头文件一般包含函数声名,全局变量,结构体定义.
头文件用<>括起来,表示是从库里找该头文件,/usr/lib/include,当用""号引起来,里边放的文件的相对路径,"./file.h"等同于 "file.h"表示当前路径,"../file.h",在上一级目录,
#include"file" 是把file里边的内容拷贝到当前文件时,file是什么文件都可以,防止反复拷贝,因为头文件定义时,加上条件编译
#ifndef 文件名
#define
文件内容
#endif
----------------------------------------
#pragma once 与
#ifndef 文件名
#define
#endif
功能一致,只是不是所有编译器都支持#pragma once
----------------------------------------
库的创建:
动态库: .so运行时动态链接指定的库文件,是由多个.o文件组成的文件
将.o文件打包成动态库.
gcc -fPIC--share file1.o file2.o -o libfile.so
库名 libfile.so 其中lib是这固定的,file是名,.so是后缀.
使用方法:
1,将库libfile.so放到/usr/lib /lib下,ldconfig 使库生效
2,将动态库与源文件一起编译
gcc sourec.c -lfile -I/dir 其中l表示链接,file是libfile去掉lib得到.-I后跟头文件路径,用来指定头文件.
gcc source.c libfile.so
修改系统指定库文件路径
/etc/ld.so.conf.d/*.conf 将路径写得些文件内,以后运行所有程序都会到这个路径里找. ldconfig 使配置生效.
不同的系统自动链接库不同,具体路径在 /etc/lib.so.conf.d/*.conf文件里,在些文件里可以添加路径,使添加的路径成为自动链接库的路径
头文件可以放到/usr/include/下可以系统会自动到这样找头文件.
静态库:
.a 在编译时与源码一起编译
ar rc 目标.a file1.o file2.o 把.o文件打包,没有编译过程.
静态库使用
gcc source.c 目标.a -o outputfile.exe
因为是静态库,所以无需链接.
------------------------------------
结构体
struct su{
int id;
char sex;
float scor;
};
struct su stu1= {1,'w',90.2};
struct su stu2 = {.id = 1, .sex = 'w'};//指定赋值
struct name
{
int a;
int b;
char c;
char d;
}
sizeof(name) = 12,CPU为了方便管理,按4个字体对齐.
struct stu
{
int a; //4Byte BBBB a
int d; //4Byte BBBB d
char b; //1Byte BBB bce
char c; //1Byte
char e; //1Byte
} stu1;
占用12个字节.但
struct stu
{
int a; //4B BBBB a
char b;//4B BB bc
char c;//1B BBBB d //int ,一定占完整的4个字节.
int d; //4B B d
char e; //1B
} stu1;
占用16个 字节.
通过 #pragma pack(num)(num 为2的幂1,2,4,8....) 可以设置字节对齐数num ,按4个字节取速度快,但会如上面所说浪费空间,因此定义结构体时,排列好成员的顺序,尽量减少空间浪费.
#prama pack()取消字节对齐,恢复成默认的字节数 (64位机是8,32位机是4)
结构体嵌套:
struct stu
{
int id;
struct info
{
charhome;
}info_1;
}stu_1;
引用 char hm = stu_1.info_1.home; 若内层结构体是匿名的,则匿名结构体的内容无法引用.
结构体的嵌套调用不会死递归,相互嵌套,需要声明一个,因为是从上到下编译.声明不是分配内存,因为声明的函数无法确定大小,无法为其分配空间,因此一个嵌套在另一个里时,只能定义成指针类型.
struct stu;
struct info
{
struct stru *stu1; //只能用指针
int a;
};
struct stu
{
int id;
char name;
};