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

一键编译+执行c语言小Demo

方法一

因为会经常写c的小demo所以也就用不上项目工程编译工具make那么导致我每次修改为代码就需要gcc demo.c -g -o demo 操作,然后就想着用shell进行自动化执行,然后雏型就出来了

c

#!/bin/bash

path=`pwd`
source_file=`ls ${path}/*.c`
gcc $source_file -o ${source_file%.*} -g
${source_file%.*}

编写如上内容,然后命名为c再放入到/usr/local/bin目录下并给它可执行权限chmod +x c,就可以在任意目录执行了

这里就是简单的获取需要执行编译脚本的路径,然后进行一个编译+运行操作

$ ls;cat demo.c                                                 [~/tmp]
demo.c
#include<stdio.h>

int main(){
   printf("hi\n");
   return 0;
}

然后执行c那么就可以直接看到结果了

$ c                                                             [~/tmp]
hi
$ ls                                                            [~/tmp]
demo*      demo.c     demo.dSYM/

很显然这只是一个简单的功能实现雏型,为了将它工具化就需要对不同的使用场景和使用功能考虑,上述的问题有:

  1. 当源代码的路径时存在一个目录和源代码同名字时
  2. 当源代码的路径存在多个.c文件时
  3. 当源代码是c++
  4. 当编译需要多个参数时

然后完善上面的问题后的脚本为

#!/bin/bash
path=`pwd`
build_type="$1"

if [ "$build_type" == "++" ];then
	c="g++";	file=`ls ${path}/*.cpp`;	shift
else
	c="gcc";	file=`ls ${path}/*.c` ;fi

main(){
	find_source_file
	build $*
}

find_source_file(){
	source_file=$(echo $file | awk '{print $1}')
	multi_file=$(echo $file | awk '{print $2}')
	if [ -z "$source_file" ];then	echo -e "\033[31mCouldn't find format $c source file\033[0m";exit ;fi
	if [ ! -z "$multi_file" ];then	echo -e "\033[31mMultiple files checked~\033[0m";	echo -e "\033[31mThe $source_file file will be used\033[0m" ;fi
}

build(){
	$c $source_file -o ${source_file%.*} -g $*
	${source_file%.*}
}

main $*

那么就来玩玩。c\cpp源代码如下:

$ cat demo.c demo.cpp                                                                                                               [/t/d/demo]
#include<stdio.h>

int main(){

   printf("c\n");
   return 0;
}
#include<iostream>

int main(){

   printf("cpp!\n");
   return 0;
}

测试

$ ls                                                                                                                                [/t/d/demo]
demo.c     demo.cpp   demo.dSYM/
$ c                                                                                                                                 [/t/d/demo]
c
$ c ++                                                                                                                              [/t/d/demo]
cpp!

当前目录存在多个源代码时

$ ls                                                                                                                                [/t/d/demo]
demo*       demo.c      demo.cpp    demo.dSYM/  democc.c    democc.cpp
$ c                                                                                                                                 [/t/d/demo]
Multiple files checked~
The /tmp/demo/demo/demo.c file will be used
c
$ c ++                                                                                                                              [/t/d/demo]
Multiple files checked~
The /tmp/demo/demo/demo.cpp file will be used
cpp!

为了方便大家搭建使用,可以执行下面代码一键搭建完成

echo "IyEvYmluL2Jhc2gKcGF0aD1gcHdkYApidWlsZF90eXBlPSIkMSIKCmlmIFsgIiRidWlsZF90eXBlIiA9PSAiKysiIF07dGhlbgoJYz0iZysrIjsJZmlsZT1gbHMgJHtwYXRofS8qLmNwcGA7CXNoaWZ0CmVsc2UKCWM9ImdjYyI7CWZpbGU9YGxzICR7cGF0aH0vKi5jYCA7ZmkKCm1haW4oKXsKCWZpbmRfc291cmNlX2ZpbGUKCWJ1aWxkICQqCn0KCmZpbmRfc291cmNlX2ZpbGUoKXsKCXNvdXJjZV9maWxlPSQoZWNobyAkZmlsZSB8IGF3ayAne3ByaW50ICQxfScpCgltdWx0aV9maWxlPSQoZWNobyAkZmlsZSB8IGF3ayAne3ByaW50ICQyfScpCglpZiBbIC16ICIkc291cmNlX2ZpbGUiIF07dGhlbgllY2hvIC1lICJcMDMzWzMxbUNvdWxkbid0IGZpbmQgZm9ybWF0ICRjIHNvdXJjZSBmaWxlXDAzM1swbSI7ZXhpdCA7ZmkKCWlmIFsgISAteiAiJG11bHRpX2ZpbGUiIF07dGhlbgllY2hvIC1lICJcMDMzWzMxbU11bHRpcGxlIGZpbGVzIGNoZWNrZWR+XDAzM1swbSI7CWVjaG8gLWUgIlwwMzNbMzFtVGhlICRzb3VyY2VfZmlsZSBmaWxlIHdpbGwgYmUgdXNlZFwwMzNbMG0iIDtmaQp9CgpidWlsZCgpewoJJGMgJHNvdXJjZV9maWxlIC1vICR7c291cmNlX2ZpbGUlLip9IC1nICQqCgkke3NvdXJjZV9maWxlJS4qfQp9CgptYWluICQqCg==" | base64 -d > /usr/local/bin/c && chmod a+x /usr/local/bin/c

方法二

后来我看到了这篇文章https://zhuanlan.zhihu.com/p/143231248 这种设计就是运用了我上面所说的没有指定Shebang字符头那么就会默认交给sh解释器执行,作者说了其实就是在c源代码里面执行shell语法进行编译自身,但同时不能被c编译器给发现错误

这里发现作者的代码有点小错误,只需要把"./$proName" 改成-> “$proName就可以了”

简单改写如下:demo.c

#if 0
pro=${0%.*} && gcc $0 -o $pro $@ && $pro && exit
#endif

#include<stdio.h>

int main(){
   printf("c\n");
   return 0;
}

首先你必须给demo.c执行权限然后直接执行./demo.c,因为没有指定Shebang字符头所以会默认将demp.c交给sh解释器执行语句,当sh解释器遇到#时会将它视为单行注释,然后会正常的执行编码命令。直到exit后退出执行

而因为#if #endif在c编译器里面也是一个合法的注视命令,所以c编译器会过滤掉文件头部一块,从而编译成功

这种方法也不错,但是需要每次都添加上述的一个头部shell代码,如果你是一个vim用户那么你可以直接在init.vim中添加上述的头部shell代码到你的c\c++模版中

	 if &filetype == 'cpp'
          call setline(1, "#if 0")
          call setline(2, "pro=${0%.*} && gcc $0 -o $pro $@ && $pro && exit")
          call setline(3, "#endif")
          call setline(4, "")
          call setline(5, "#include<iostream>")
          call setline(6, "")
          call setline(7, "int main(){")
          call setline(8, "")
          call setline(9, "   printf(\"\\n\");")
          call setline(10, "   return 0;")
          call setline(11, "}")
      endif
      if &filetype == 'c'
    	...
      endif

方法三

还有一种就是使用tcc,我不想额外的搭建环境,所以大家自行探索

相关文章:

  • 【网络编程】第一章 网络基础(协议+OSI+TCPIP+网络传输的流程+IP地址+MAC地址)
  • 第九章 堆排序与TOPK问题
  • 让学前端不再害怕英语单词(一)
  • CSDN编程竞赛 ——— 第十期
  • ssh外网访问内网服务器
  • XSS绕过安全狗WAF
  • Java项目:JSP高校新生报到迎新管理系统
  • Linux kprobe原理
  • 03、Spring中的静态代理JDK动态代理CGLB动态代理
  • echarts——实现3D地图+3D柱状图 效果——粗糙代码记录——技能提升
  • 从一道题到贪心入门
  • Redis缓存的雪崩、穿透、击穿
  • 腾讯云COS+PicGo+Typora十分钟搭建自己的图床
  • 第十四届蓝桥杯(Web应用开发)模拟赛1期-大学组
  • js逆向tips-某思录登录
  • 为了摸鱼,我开发了一个工具网站
  • OpenCV图像处理——(实战)答题卡识别试卷
  • 朋友电脑密码忘了,我当场拔了她的电源,结果。。。
  • SpringBoot: Controller层的优雅实现
  • LeetCode135. 分发糖果(贪心算法)