笔记:Linux C语言编程基本原理与实践

简介: 笔记:Linux C语言编程基本原理与实践

C语言的应用:

1、Linux嵌入式(小工具)(C语言小巧灵活、语法简单、适合做小工具)

linux/unix系统就是由各种各样的小工具集成得来的。


2、和硬件打交道的程序

a、操作系统:苹果系统,安卓系统,windoows

b、ARM嵌入式、单片机、Arduino


3、有高性能要求的应用程序

著名的WEB服务器,NGINX=apache*10


环境

centos https://www.centos.org/

ubuntu https://ubuntu.com/

常用指令

# ubuntu 安装vim编辑器
$ apt-get update
$ apt-get install vim
# 编译器
$ cc -v
$ gcc -v

VIM命令模式


i    (插入模式 或 当前光标前插入字符)
Esc     (返回命令行模式)
:w    (保存)
a    (当前光标后插入字符)
:q     (退出VIM)
Shitf + a   (在行尾插入字符)
Shift + i   (在行手插入字符)
o      (下一行插入字符)
Shift + o   (在当前行上行插入字符)
x     (删除单个字符)
dd    (删除整行字符)

C程序

hello.c

#include <stdio.h>
int main(){
    printf("hello world\n");
    return 0;
}

编译执行


# 编译
$ cc hello.c 
# 或者
$ gcc hello.c
# 执行
$ ./a.out

代码分布在多个源文件

1、放在一个文件


hello.c


#include <stdio.h>  // 系统目录中查找
int max(int a, int b){
    if (a > b) {
        return a;
    } else {
        return b;
    }
}
int main(){
    int a = 1;
    int b = 2;
    int ret = max(a, b);
    printf("max value is %d\n", ret);
    // max value is 2
    return 0;
}

编译执行 执行输出文件,默认是a.out


$ gcc hello.c -o hello.out
$ ./hello.out

2、放在多个文件


hello.c


#include <stdio.h>  // 系统目录中查找
int main(){
    int a = 1;
    int b = 2;
    int ret = max(a, b);
    printf("max value is %d\n", ret);
    // max value is 2
    return 0;
}

max.c


int max(int a, int b){
    if (a > b) {
        return a;
    } else {
        return b;
    }
}

多文件编译执行


$ gcc max.c hello.c -o hello.out
$ ./hello.out

此时会有警告


3、声明引用


hello.c


#include <stdio.h>  // 系统目录中查找
#include "max.c"    // 相对目录中查找
int main(){
    int a = 1;
    int b = 2;
    int ret = max(a, b);
    printf("max value is %d\n", ret);
    // max value is 2
    return 0;
}

编译执行


$ gcc hello.c -o hello.out
$ ./hello.out

头文件与函数定义分离

1、两个文件分别编译


gcc参数:


-c compile 只编译源文件但不链接 *.o
-o out 指定输出文件名 默认a.out

分开编译需要注释include


#include <stdio.h>  // 系统目录中查找
// #include "max.c"    // 相对目录中查找
int main(){
    int a = 1;
    int b = 3;
    int ret = max(a, b);
    printf("max value is %d\n", ret);
    // max value is 2
    return 0;
}

编译源文件


# 先编译max.c文件
$ gcc -c max.c -o max.o
# 再编译hello.c文件
$ gcc max.o hello.c

2、三个文件分别编译


min.c


int min(int a, int b){
    if (a > b) {
        return a;
    } else {
        return b;
    }
}

hello.c


#include <stdio.h>
int main(){
    int a = 1;
    int b = 3;
    int maxValue = max(a, b);
    printf("max value is %d\n", maxValue);
    int minValue = min(a, b);
    printf("min value is %d\n", minValue);
    return 0;
}
# 编译min.c
$ gcc -c min.c
# 编译hello.c
$ gcc min.o max.o hello.c -o hello.out

3、引入头文件


min.h


int min(int a, int b);

max.h


int max(int a, int b);

hello.c


#include <stdio.h>  // 系统目录中查找
#include "min.h"    // 引入头文件
#include "max.h"    
int main(){
    int a = 1;
    int b = 3;
    int maxValue = max(a, b);
    printf("max value is %d\n", maxValue);
    int minValue = min(a, b);
    printf("min value is %d\n", minValue);
    return 0;
}

编译执行


$ gcc min.o max.o hello.c -o hello.out
$ ./hello.out

Makefile

# 删除所有.o结尾的文件
$ rm *.o

make工具可以将大型的开发项目分成若干个模块


make内部使用了gcc


$ apt-get install make
$ make -v

Makefile 使用tab缩进


# 注释
hello.out:max.o min.o hello.c
    gcc max.o min.o hello.c -o hello.out
max.o:max.c
    gcc -c max.c
min.o:min.c
    gcc -c min.c

执行编译


$ make

main函数中的return

main.c


# include <stdio.h>
int main(int argv, char* argc[]){
    printf("hello world\n");
    return 0;
}

查看程序返回


# 编译并执行程序
gcc main.c -o main.out && ./main.out
# 查看程序运行结果
$ echo $?

main函数中的参数

main.c


# include <stdio.h>
int main(int argv, char* argc[]){
    for(int i=0; i < argv; i++){
        printf("argc[%d]=%s\n", i, argc[i]);
    }
    return 0;
}
$ ./main.out name age
argc[0]=./main.out
argc[1]=name
argc[2]=age

argv 参数的个数

argc 参数的内容


标准输入流输出流以及错误流

# include <stdio.h>
int main(){
    // 接收输入
    int a;
    scanf("%d", &a);
    // 输出数据
    printf("input value is %d\n", a);
    return 0;
}
stdin  标准输入 eg: 键盘输入
stdout 标准输出 eg: 终端输出
stderr 标准错误 eg: 错误输出
# include <stdio.h>
int main(){
    // printf("please input a value\n");
    fprintf(stdout, "please input a value\n");
    int a;
    // scanf("%d", &a);
    fscanf(stdin, "%d", &a);
    if(a < 0){
        fprintf(stderr, "the value must > 0\n");
        return 1;
    } else{
        return 0;
    }
}

标准输入输出流以及错误流重定向

加法计算器小程序


接收两个输入,计算两个数字的和,并输出


#include <stdio.h>
int main(){
    int a; 
    int b;
    printf("input a:\n");
    scanf("%d", &a);
    printf("input b:\n");
    scanf("%d", &b);
    int ret = a + b;
    printf("a + b = %d\n", ret);
    return 0;
}

1、输出流重定向

# 追加
$ ./mian.out 1>> a.txt 
# 或者
$ ./mian.out >> a.txt 
# 覆盖
$ ./mian.out > a.txt

输出结果 a.txt


input a:
input b:
a + b = 8

2、输入流重定向


输入文件 input.txt

3
4
$ ./main.out < input.txt
input a:
input b:
a + b = 7

3、错误流重定向


#include <stdio.h>
int main(){
    int a;
    printf("input value:\n");
    scanf("%d", &a);
    if( a > 0){
        printf("value %d > 0\n", a);
        return 0;
    } else{
        fprintf(stderr, "value %d < 0\n", a);
        return 1;
    }
}
$ ./main.out 1>stdout.txt 2>stderr.txt

4、同时操作标准输入、标准输出、错误流

stdin.txt


-10

执行程序

$ ./main.out 1>stdout.txt 2>stderr.txt < stdin.txt

stdout.txt


input value:

stderr.txt


value -10 < 0:

管道原理及应用

前一个命令的输出,作为后一个命令的输入

# 查看当前目录下文件
ls
# 查看根目录下文件
ls / 
# 查看/etc目录下文件
ls /etc
# 在/etc目录下查找包含ab字符的文件名
ls /etc | grep ab
# 查询进程
ps -e | grep ssh

sum.c


#include 
/**
对输入求和,并输出求和结果和输入个数
格式:sum:count
eg: 400,2
*/
int main(){
    int sum = 0;
    int count = 0;
    int var;
    while(1){
        scanf("%d", &var);
        if(var == 0){
            break;
        } else{
            sum += var;
            count++;
        }
    }
    printf("%d,%d\n", sum, count);
    return 0;
}

avg.c


#include 
/**
对输入计算平均值
格式:sum,count
eg: 500,2
输出:250.000
*/
int main(){
    int sum;
    int count;
    scanf("%d,%d", &sum, &count);
    float avg = sum / count;
    printf("%f\n", avg);
    return 0;
}

input.txt


500
400
600
0
# 编译
$ gcc sum.c -o sum.out
$ gcc avg.c -o avg.out
# 通过重定向输入和管道处理,先求和再计算平均值
$ ./sum.out < input.txt | ./avg.out
500.000000


相关文章
|
8月前
|
安全 算法 Ubuntu
Linux(openssl)环境:编程控制让证书自签的技巧。
总结:在Linux环境中,OpenSSL是一个非常实用的工具,可以帮助我们轻松地生成自签名证书。通过上述三个简单步骤,即可为内部网络、测试环境或开发环境创建自签名证书。但在公共访问场景下,建议购买经过权威认证机构签发的证书,以避免安全警告。
396 13
|
10月前
|
JavaScript Ubuntu Linux
如何在阿里云的linux上搭建Node.js编程环境?
本指南介绍如何在阿里云Linux服务器(Ubuntu/CentOS)上搭建Node.js环境,包含两种安装方式:包管理器快速安装和NVM多版本管理。同时覆盖全局npm工具配置、应用部署示例(如Express服务)、PM2持久化运行、阿里云安全组设置及外部访问验证等步骤,助你完成开发与生产环境的搭建。
|
11月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
224 26
|
11月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
228 17
|
Linux
《循序渐进LINUX》笔记
基础知识、服务器搭建、系统管理、性能调优、集群应用 1、swap物理内存两倍 2、根分区5G 3、/boot 100M 4、查看系统硬件信息: cat /proc/meminfo cat /proc/cpuinfo 查看磁盘信息: fd...
1439 0
|
4月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
555 1
二、Linux文本处理与文件操作核心命令
|
4月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
359 137
|
4月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
836 57
|
3月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
705 2
|
4月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
405 0
Linux内存问题排查命令详解