再学C语言,复习&笔记。
系列顺序:
Linux C语言编程基本原理与实践
Linux C语言指针与内存
Linux C语言结构体
更多Linux知识:
一天一点linux
常用指令
sudo
管理员权限
sudo apt-get update
更新资源(安装软件前最好先更新资源)
sudo apt-get install vim(软件名称)
安装某软件
cd ~
进入home目录
pwd
显示当前目录路径
ls
显示当前文件夹下所有文件夹及文件
ls -l
进入当前目录的文件夹目录后查看当前文件夹包含的文件/文件夹的类型、创建时间、用户权限、用户和用户组
(最前面是“d”为文件夹;“-”为普通类型的文件)
touch + 文件名
新建文件
rm + 文件名
删除文件
mkdir + 目录名
新建目录
vi(vim) + 文件名
使用vim编辑文件
clear
清洁屏幕
cc -v
检查编译器
gcc -v
检查编译器
VIM命令模式:
dd
删除整行
i
在光标前面插入
a
在光标后面插入
x
删除单个字符
Shift + a
行尾插入
Shift + i
行首插入
o
下一行插入
Shift + o
上行插入
:$
跳到代码末尾
第一个Linux C程序
编译文件:
1 | cc a.c |
会得到a.out
编译文件后查看文件权限:
rw-:可读、可写
rwx:可读、可写、可执行
三个rwx 1创建用户 2与创建用户在同一个用户组 3任意用户
运行文件:
“.” 当前路径
“./” 当前路径下的文件
执行文件:./a.out
多文件操作
sp max.c
新建max.c文件(窗口打开多个文件)
ctrl + w +下箭头
跳转到下一个编辑框
ctrl + w +下箭头
跳转到上一个编辑框
对应行数+d+d
剪切光标下相应行数的程序
9dd(代码占九行,剪切代码)
按p
粘贴在剪切板的程序
set nu
打开行号
:wqa
保存所有文件并退出
1 | gcc hello.c -o hello.out 指定编译文件(-o 给编译后的文件重命名) |
分开编译:
1 | gcc -c 文件名.c -o 文件名.o |
函数可以先编译成.o文件,然后再和主文件一起编译成可执行文件。在源代码多的时候可以提高效率。
例如:
1 | gcc -c max.c -o max.o |
gcc编译流程分为4步:
预处理(Pre-Processing) -> 编译(Compling) -> 汇编(Assembling) -> 连接(Linking)
预处理:处理#include、#define、#ifdef 等宏命令
编译:把预处理完的文件编译为汇编程序.s
汇编:把汇编程序.s编译为.o二进制文件
链接:把多个二进制文件.o集合(链接)成一个可执行文件
使用别人的静态库.o文件(机器码,无法查看原代码)可以创建.h文件,然后在源程序中#include<文件名.h>来引用。
hello.c
1 |
|
max.c
1 | int max(int a, int b) |
min.c
1 | int min(int a, int b) |
max.h
1 | int max(int a, int b); |
min.h
1 | int min(int a, int b); |
makeFile的编写与使用
make工具可以将大型的开发项目分成若干个模块。
make工具可以很清晰和很快捷的编译和整理源文件。
rm *.o
表示删除所有.o文件
make -v
检查make版本
vi Makefile 编译修改过的部分
输出文件:源文件
一个tab gcc命令
从上到下逐层求精
eg:
1 | hello.out:max.o min.o hello.c |
最后用make命令执行
重复使用make时,中间生成过的文件不需要再生成,没有修改过的文件不用再编译,会直接跳过该段代码,所以更加节省编译时间。
gcc-c
参数的意义:
-c
参数是将源代码编译成“目标文件 .o”,不进行连接
后面多个目标文件可通过-o链接成可执行文件。
不使用这个参数时gcc会直接进行编译链接,生成可执行文件。
main函数详解
1 |
|
gcc main.c -o main.out && ./ main.out
echo $? 执行成功则返回0
参数
1 | int main(int argc,char* argv[]) |
./out.c -l -s asd qwe
输出为:
1 | argc is 5 |
标准输入流输出流以及错误流
cio.c
1 |
|
在输入a.out时,程序执行,系统给程序提供了一个进程,当程序启动时,系统也提供给程序一系列的指针。linux将所有的外设(摄像头,打印机等),都视为文件。当启动应用程序时候,会产生三个文件(stdin,stdout,stderr,即标准输入,输出,错误流)。
默认情况下,输入流就是键盘,stdout默认为显示器,可切换为网卡或者打印机。
1 | printf("Please input the value a:\n"); |
因为stdout默认是显示器,上两句就是等价的,printf其实就是fprintf封装后得到的。
同理,scanf和fscanf等价:
1 | scanf("%d", &a); |
错误流:
1 | if(a < 0){ |
通过返回值1和0,让程序知道出错了。再次编译cc cio.c -o a2.out,我们运行a2.out,输入2则正常执行,当输入-1,则有对应的提示,即错误流发挥作用。
其实Linux这个很大的系统,就是由这些类似的小工具完成的。当等于0是为正确,错的话为其他值。
标准的输入流,输出流,以及错误流还可以重定向。
Linux几乎可以用于任何领域,这里我们不得不提出linux的通道,管道起到了很重要的作用,不同应用程序之间要配合使用,就需要用到管道。
先说输入流,输出流和错误流的重定向机制:
1 |
|
cc main.c
得到a.out,运行a.out,我们分别输入3和5输入到终端。我们标准输出流是1,输出入是0。
>>
标准输出流重新定向符
1 | ./a.out 1>> a.txt 输出到a.txt(默认为1,可不写1) |
执行命令后,分别输入3回车后再输入5。再使用命令cat a.txt,可以看到已经输出到文件里的内容。
错误流重定向:1>标准输出流重定向 2>标准错误流重定向
./a.out 1>t.txt 2>f.txt 将正确的输出流重定向输出到t.txt,错误的输出流重定向输出到f.txt
<<
标准输入流重新定向符
1 | ./a.out < input.txt 将input.txt的内容作为输入流传递给程序a.out |
综合使用标准输出流、标准错误流、标准输入流
1 | ./a.out 1>t.txt 2>f.txt <input.txt |
管道原理及应用
ls /
查看根目录
ls /etc/
查看Linux默认配置目录
ls /etc/ | grep 关键字符
将etc文件输出到一个管道
|
管道
eg. 要查找某个目录下有多少个文件名包含“ab”,可以写
1 | ls /etc/ | grep ab |
将前一个程序输出流重定向到grep,通过管道得到需要的内容。
ps -e | grep ssh
ps查看当前的进程,当前操作系统是否开启ssh进程
管道使用demo
程序avg.c,求任意个数的平均值:
1 |
|
cc avg.c -o avg.out
再写一个统计输入的程序input.c:
1 |
|
cc input.c -o input.out
结合使用以上两个程序,将所有数据进行统计,执行input.out,之后通过管道经过avg.out计算平均值。
./input.out | ./avg.out
以上就是通过管道,将两个小程序连接起来得到更复杂的程序的过程。