当前位置: 首页 > article >正文

shell数组 Linux分文件 make工具

shell中的数组

shell 支持稀疏数组

格式:数组名=(初始值1 初始值2,……)

数组名=([下标]=初始值 [下标]=初始值……)下标可以不连续

arr=([10]=10 [0]=0)

访问数组中的元素

${数组名[下标]} --> 获取数组中指定下标元素的值

获取数组中的所有元素

${数组名[*]} ---> 获取数组中所有元素

${数组名[@]} ---> 获取数组中所有元素

获取数组中元素的个数

${#数组名[*]} ---> 获取数组中元素个数

${#数组名[@]} ---> 获取数组中元素个数

${#arr[下标]} ---> 获取数组中指定下标元素的长度(字符长度)

数组切片

取数组中某一段元素的值

格式:

${数组名[*]:起始位置(起始下标):长度}

${数组名[@]:起始位置(起始下标):长度}

文件

整个工程包含

多个.c多个 .h 文件

main.c ---> main() //main函数其余文件main.c调用

xxx.c ----> 多个.c文件,封装函数实现多个功能(不同功能函数接口)

.h 头文件

包含

  1. 包含其他头文件
  2. 函数声明
  3. 构造数据类型
  4. 宏定义
  5. 重定义名字
  6. 全局变量

include 引用时 " " 和 <> 的区别

#include <stdio.h>

系统定义的头文件:去系统目录下查找头文件

#include "add.h"

自定义头文件:先从当前目录下查找,如果没有再去系统目录下查找头文件

条件编译

编译器根据条件真假决定是否编译相关代码

根据宏是否定义

语法格式

#ifdef <macro>

...

#else

...

#endif

#include "function.h"
#define DEF

int main(int argc, char const *argv[])
{
    #ifdef DEF
        printf("YES\n");
    #else
        printf("NO\n");
    #endif
    return 0;
}

根据是否为

#if <macro>

...

#esle

...

#endif

#include <stdio.h>
#include "function.h"
#define DEF 0

int main(int argc, char const *argv[])
{
    #if DEF
        printf("YES\n");
    #else
        printf("NO\n");
    #endif
    return 0;
}

根据宏是否定义,作用:防止头文件重复包含(加上包不错)

#ifndef <macro> 注意两个相同

#define <macro>

....

#endif

gcc编译步骤

预处理: 处理以#开头的内容,展开头文件、替换宏定义、删除注释,但是不会进行语法检查

gcc -E xxx.c -o xxx.i

编译检查语法错误有错报错没错 .i 文件转换成 .s 汇编文件

gcc -S xxx.i -o xxx.s

汇编汇编文件转化成二进制文件(不可执行)

gcc -c xxx.s -o xxx.o

链接链接库文件将不可执行的二进制文件转化成可执行的二进制文件

gcc xxx.o -o xx

gcc xx.c 默认生成 a.out

gcc xxx.c -o xxx

make工具

  1. 工程管理器管理较多文件

Make 工程管理器也就是个"自动编译管理器",这里的"自动"

是指它能够根据文件时间戳发现更新过的文件而减少编译工作量同时它通过读入

Makefile 文件的内容来执行大量的编译工作

  1. make工具的作用

当项目中包含了多个.c文件,但只对其中一个文件进行了修改,那用 gcc 编译会将所有的文件从头到尾编译一遍,这样的效率非常低

所以通过 make 工具,可以查找到修改过的文件(根据时间戳),只对修改过的文件进行编议,这样大大的减小的编译时间,提高编译效率

  1. Makefile是make读入的唯一配置文件

Makefile工程文本文件

  1. Makefile编写格式

目标: 依赖

<tab>命令

Makefile 根据以下步骤书写

gcc xxx.o -o xxx

gcc -c xxx.c -o xxx.o

一个Makefile文件

main: main.o function.o
	gcc main.o function.o -o main
main.o: main.c
	gcc -c main.c -o main.o
function.o: function.c
	gcc -c function.c -o function.o

目标: 伪命令

伪命令它的目的不是创建目标文件,而是执行下面的命令

# 第一个版本
all: main # 一般makefile中的第一个目标都是 all:可执行文件
#为了保证,最后makefile文件执行后一定会生成一个可执行文件

main: main.o function.o
	gcc main.o function.o -o main
main.o: main.c
	gcc -c main.c -o main.o
function.o: function.c
	gcc -c function.c -o function.o

.PHONY: clean
clean:
	rm -rf *.o main

执行:make clean

规则中 rm 命令不是为了创建 clean 这个文件而是执行删除命令。当工作目录中不存在clean 命名文件时,执行 make clean 命令 rm -rf *.o main总会被执行。

如果避免同名文件加 .PHONY:伪命令

Makefile变量

自己定义的变量:一般用大写表示变量名,取变量值用 $(变量名)

赋值方式: = := += ?=

  1.   = ---->递归赋值(以最后一次赋值为准)
  2.   := ---->立即赋值 (当前是什么值就立即是什么值)
  3.   += ---->追加赋值(追加新的值)
  4.   ?= ---->条件赋值(判断之前是否定义,如果定义不重新赋值,如果没有定义,则重新赋值)

预定义变量

系统预先定义好的一些变量,可能有默认值可能没有

RM 文件删除程序的名称,默认值为 rm -f

CC C编译器名称默认值cc

CPP C预编译器名称默认值$(CC)-E

CFLAGS C编译器选项默认值

OBJS 生成二进制文件或者目标文件自己定义

# 第二个版本
EXE=main
OBJS=main.o function.o
CC=gcc
CFLAGS=-c -g -Wall  # -g:调试	-Wall: 显示警告

all: $(EXE)
$(EXE): $(OBJS)
	$(CC) $(OBJS) -o $(EXE)
main.o: main.c
	$(CC) $(CFLAGS) main.c -o main.o
function.o: function.c
	$(CC) $(CFLAGS) function.c -o function.o

.PHONY: clean
clean:
	$(RM) $(OBJS) $(EXE)

引入自动变量通配符

$< 第一个依赖文件

$@ 目标文件的完整名称

$^ 所有不重复的依赖文件以空格分开(自动)

通配符

%是一种(字符串的)模式匹配Makefile作用有一个.o匹配一个同名.c

%.o:%.c

EXE=main
OBJS=main.o function.o
CC=gcc
CFLAGS=-c -g -Wall  # -g:调试	-Wall: 显示警告

all: $(EXE)
$(EXE): $(OBJS)
	$(CC) $^ -o $@
%.o: %.c
	$(CC) $(CFLAGS) $< -o $@

.PHONY: clean
clean:
	$(RM) $(OBJS) $(EXE)

引入函数

make中提供了内置函数

因为内置函数是帮助程序员查找文件信息的,所以要求在查找路径下,只要程序需要的.c文件,没有其他程序的.c文件

wildcard

功能根据给的条件获取指定文件名(找文件名的功能)

$(wildcard 指定字符串的格式)

$(wildcard *.c) ---->找到当前路径下所有.c文件文件名

patsubst

功能模式匹配替换字符串

$(patsubst 源格式.c,目标格式,要替换的字符串)

$(patsubst %.c,%.o,main.c fun.c) ---> 获取到 main.c fun.c字符串,根据模式匹配,得到 main.o fun.o 字符串每一个参数之间以逗号作为分隔,要替换的字符串之间以空格作为分隔

#第四个版本
EXE=main
FILES=$(wildcard *.c)
OBJS=$(patsubst %.c,%.o,$(FILES))
CC=gcc
CFLAGS=-c -g -Wall

all: $(EXE)
$(EXE): $(OBJS)
	$(CC) $^ -o $@
%.o: %.c
	$(CC) $(CFLAGS) $< -o $@
                                         
.PHONY: clean
clean:
	$(RM) $(OBJS) $(EXE)


http://www.kler.cn/a/411822.html

相关文章:

  • MySQL INSERT CRTATE DELETE DORP UPDATE WHERE 的用法
  • 【C++】读取数量不定的输入数据
  • 基于混合ABC和A*算法复现
  • NLP论文速读(剑桥大学出品)|分解和利用专家模型中的偏好进行改进视觉模型的可信度
  • MySQL系列之数据类型(Numeric)
  • 【JavaEE初阶】多线程初阶下部
  • 金铲铲S13双城之战自动拿牌助手
  • emotion2vec语音情感识别 - python 实现
  • 什么是 C++ 中的 Lambda 表达式?Lambda 表达式可以捕获哪些类型的变量?有哪些捕获方式?
  • python的交互式编程
  • 触想工业显示器应用于光伏自动化设备,助力绿色低碳能源发展
  • YOLOv8模型pytorch格式转为onnx格式
  • js.二叉树的层序遍历2
  • [C++]:IO流
  • JavaWeb后端开发知识储备2
  • 嵌入式QT中UDP通信实现方法
  • 单例模式入门
  • 文件系统的作用
  • C++条件编译指令:#if、#elif、#ifdef、#ifndef、#elifdef、#elifndef、#else、#endif
  • On-Chip-Network之routing
  • [HarmonyOS] 解决HMRouter路由地址无法抽取的问题
  • C#上机练习66-70
  • 网络安全防范
  • 鸿蒙HarmonyOS学习笔记(4)
  • 3D导航案例
  • 钉钉与企业微信机器人:助力网站定时任务高效实现