# 编程技巧,第 1 部分
> 原文:<https://github.com/angrave/SystemProgramming/wiki/Programming-Tricks%2C-Part-1>
## 使用`cat`作为 IDE
谁需要编辑? IDE?我们可以使用`cat`!您已经看到`cat`用于读取文件的内容,但它也可用于读取标准输入并将其发送回标准输出。
```
$ cat
HELLO
HELLO
```
要完成从输入流中读取,请按`CTRL-D`关闭输入流
让我们使用`cat`将标准输入发送到文件。我们将使用'&gt;'将其输出重定向到文件:
```
$ cat > myprog.c
#include <stdio.h>
int main() {printf("Hi!");return 0;}
```
(注意!不允许删除和撤消...)完成后按`CTRL-D`。
## 使用`perl`正则表达式编辑代码(又名“记住你的 perl 馅饼”)
如果要更改多个文本文件(例如源代码),则使用正则表达式是一个有用的技巧。 `perl`使得编辑文件非常容易。记住'perl pie'并在网上搜索......
一个例子。假设我们要在当前目录的所有.c 文件中将序列“Hi”更改为“Bye”。然后我们可以编写一个简单的替换模式,它将在所有文件中的每一行上执行:
```
$ perl -p -i -e 's/Hi/Bye/' *.c
```
(如果你弄错了,不要惊慌,原始文件仍然存在;他们只有扩展名.bak)显然你可以用正则表达式做更多的事情而不是改变 Hi 到 Bye。
## 使用你的 shell `!!`
要重新运行最后一个命令,只需键入`!!`并按`return`重新运行以 g 类型`!g`开头的最后一个命令,然后按`return`
## 使用你的 shell `&&`
厌倦了运行`make`或`gcc`然后运行程序,如果编译正常?相反,使用&amp;&amp;将这些命令链接在一起
```
$ gcc program.c && ./a.out
```
## Make 可以做的不仅仅是制作
您也可以尝试在 Makefile 中添加一行以进行编译,然后运行您的程序。
```
run : $(program)
./$(program)
```
然后跑
```
$ make run
```
将确保您所做的任何更改都已编译,并一次运行您的程序。也适合一次测试多个输入。虽然您可能只想为此编写常规 shell 脚本。
## 你的邻居太高效了吗? C 预处理器救援!
使用 C 预处理器重新定义常用关键字,例如
```c
#define if while
```
Protip:将此行放入标准包含的内容之一,例如/usr/include/stdio.h
## 当 C 具有预处理器时,谁需要功能
好的,所以这更像是一个问题。使用看起来像函数的宏时要小心......
```c
#define min(a,b) a<b?a:b
```
a 和 b 的最小值的完全合理的定义。然而,预处理器只是一个简单的文本管理器,所以优先级可以咬你:
```c
int value = -min(2,3); // Should be -2?
```
扩大到
```
int value = -2<3 ? 2 :3; // Ooops.. result will be 2
```
部分修复是用`()`包装每个参数,用()包装整个表达式:
```c
#define min(a,b) ( (a) < (b) ?(a):(b) )
```
不过这仍然是 _ 而不是 _ 的功能!例如,你能看出为什么`min(i++,10)`可能会增加一次或两次!?
- UIUC CS241 系统编程中文讲义
- 0. 简介
- #Informal 词汇表
- #Piazza:何时以及如何寻求帮助
- 编程技巧,第 1 部分
- 系统编程短篇小说和歌曲
- 1.学习 C
- C 编程,第 1 部分:简介
- C 编程,第 2 部分:文本输入和输出
- C 编程,第 3 部分:常见问题
- C 编程,第 4 部分:字符串和结构
- C 编程,第 5 部分:调试
- C 编程,复习题
- 2.进程
- 进程,第 1 部分:简介
- 分叉,第 1 部分:简介
- 分叉,第 2 部分:Fork,Exec,等等
- 进程控制,第 1 部分:使用信号等待宏
- 进程复习题
- 3.内存和分配器
- 内存,第 1 部分:堆内存简介
- 内存,第 2 部分:实现内存分配器
- 内存,第 3 部分:粉碎堆栈示例
- 内存复习题
- 4.介绍 Pthreads
- Pthreads,第 1 部分:简介
- Pthreads,第 2 部分:实践中的用法
- Pthreads,第 3 部分:并行问题(奖金)
- Pthread 复习题
- 5.同步
- 同步,第 1 部分:互斥锁
- 同步,第 2 部分:计算信号量
- 同步,第 3 部分:使用互斥锁和信号量
- 同步,第 4 部分:临界区问题
- 同步,第 5 部分:条件变量
- 同步,第 6 部分:实现障碍
- 同步,第 7 部分:读者编写器问题
- 同步,第 8 部分:环形缓冲区示例
- 同步复习题
- 6.死锁
- 死锁,第 1 部分:资源分配图
- 死锁,第 2 部分:死锁条件
- 死锁,第 3 部分:餐饮哲学家
- 死锁复习题
- 7.进程间通信&amp;调度
- 虚拟内存,第 1 部分:虚拟内存简介
- 管道,第 1 部分:管道介绍
- 管道,第 2 部分:管道编程秘密
- 文件,第 1 部分:使用文件
- 调度,第 1 部分:调度过程
- 调度,第 2 部分:调度过程:算法
- IPC 复习题
- 8.网络
- POSIX,第 1 部分:错误处理
- 网络,第 1 部分:简介
- 网络,第 2 部分:使用 getaddrinfo
- 网络,第 3 部分:构建一个简单的 TCP 客户端
- 网络,第 4 部分:构建一个简单的 TCP 服务器
- 网络,第 5 部分:关闭端口,重用端口和其他技巧
- 网络,第 6 部分:创建 UDP 服务器
- 网络,第 7 部分:非阻塞 I O,select()和 epoll
- RPC,第 1 部分:远程过程调用简介
- 网络复习题
- 9.文件系统
- 文件系统,第 1 部分:简介
- 文件系统,第 2 部分:文件是 inode(其他一切只是数据...)
- 文件系统,第 3 部分:权限
- 文件系统,第 4 部分:使用目录
- 文件系统,第 5 部分:虚拟文件系统
- 文件系统,第 6 部分:内存映射文件和共享内存
- 文件系统,第 7 部分:可扩展且可靠的文件系统
- 文件系统,第 8 部分:从 Android 设备中删除预装的恶意软件
- 文件系统,第 9 部分:磁盘块示例
- 文件系统复习题
- 10.信号
- 过程控制,第 1 部分:使用信号等待宏
- 信号,第 2 部分:待处理的信号和信号掩码
- 信号,第 3 部分:提高信号
- 信号,第 4 部分:信号
- 信号复习题
- 考试练习题
- 考试主题
- C 编程:复习题
- 多线程编程:复习题
- 同步概念:复习题
- 记忆:复习题
- 管道:复习题
- 文件系统:复习题
- 网络:复习题
- 信号:复习题
- 系统编程笑话