代码片段
输出错误信息并退出
#define err_exit(x) do { printf("%s\n", x); exit(1); } while (0)
输出系统错误信息并退出
#define err_sys(x) do { perror(x); exit(1); } while (0)
清空输入缓存
while ((c = getchar()) != '\n' && c != EOF)
;
scanf("%*[^\n]");
setbuf(stdin, NULL);
终端屏蔽显示
system("stty -echo");
system("stty echo");
按任意键继续
system("stty raw -echo");
printf("Press any key to continue ...");
getchar();
system("stty -raw echo");
获取文件大小
#include <sys/stat.h>
off_t get_file_size(const char *path)
{
struct stat sb;
if (stat(path, &sb) < 0)
return -1;
return sb.st_size;
}
指定数组的元素來进行初始化
我们可以指定数组的元素來进行初始化。 这非常有用,特别是当我们需要根据一组 #define 來保持某种映射关系的同步更新时
如下,假设我们想为每个错误码提供一个错误描述的字符串。 为了确保数组保持了最新的定义,无论头文件做了任何修改或增补,我们都可以用这个数组指定的语法
这样就可以静态分配足够的空间,且保证最大的索引是合法的, 同时将特殊的索引初始化为指定的值,并将剩下的索引初始化为 0
#include <stdio.h>
/* Entries may not correspond to actual numbers. Some entries omitted. */
#define EINVAL 1
#define ENOMEM 2
#define EFAULT 3
/* ... */
#define E2BIG 7
#define EBUSY 8
/* ... */
#define ECHILD 12
int main()
{
char *err_strings[] = {
[0 ] = "Success",
[EINVAL] = "Invalid argument",
[ENOMEM] = "Not enough memory",
/* ... */
[E2BIG ] = "Argument list to long",
[EBUSY ] = "Device or resource busy",
/* ... */
[ECHILD] = "No child processe",
};
printf("%s\n", err_strings[0]);
return 0;
}
用结构体与联合体的字段名称來初始化数据
当我们不想将所有字段初始化为 0 时候,这种做法可以很容易的在编译时就生成结构体, 而不需要专门调用一个初始化函数
#include <stdio.h>
struct point {
int x;
int y;
int z;
};
int main()
{
struct point p = {.x = 3, .y = 4, .z = 5};
printf("%d\n%d\n%d\n", p.x, p.y, p.z);
return 0;
}
md5 加密
编译时加上 -lcrypt
#include <stdio.h>
#include <string.h>
#include <crypt.h>
int main()
{
const char salt[] = "$1$mwumsmsp$";
char *cp;
char s[69];
while (1) {
scanf("%69s", s);
cp = crypt(s, salt);
cp += strlen(salt);
puts(cp);
}
return 0;
}
字符串位操作
/* 将指定位的比特位设为set */
void set_num_bit(char *s, int n, int set)
{
if (set) {
*(s + n/8) |= (0x80 >> n%8);
} else {
*(s + n/8) &= ~(0x80 >> n%8);
}
}
/* 取得指定位的比特位 */
int get_num_bit(char *s, int n)
{
return ((*(s + n/8) << n%8) & 0x80) == 0x80 ? 1 : 0;
}
字符串 + 数字
#include <string.h>
#include <stdio.h>
/* max 999 */
#define TIMES 6
int main(int argc, char *argv[])
{
/* strlen("input-999") = 9 */
char path[10] = "input-";
/* strlen("999") = 3 */
char number[4];
for (int i = 1; i <= TIMES; i++) {
path[6] = '\0';
sprintf(number, "%d", i);
printf("%s\n", strncat(path, number, 3));
}
return 0;
}
评断字符串是否为数字
#include <string.h>
int is_digit(char *s)
{
for (int i = 0; i < strlen(s); i++) {
if (s[i] < '0' || s[i] > '9')
return FALSE;
}
return TRUE;
}
使用二级指针作为矩阵
#include <stdlib.h>
#include <stdio.h>
struct matrix {
int row;
int col;
int **matrix;
};
/*
* 初始化
*/
void init_matrix(struct matrix *matrix, int row, int col)
{
matrix->row = row;
matrix->col = col;
matrix->matrix = (int **)malloc(sizeof(int *) * row);
for (int i = 0; i < row; i++) {
matrix->matrix[i] = (int *)malloc(sizeof(int) * col);
}
}
/*
* void init_matrix(int ***p, int row, int col)
* {
* *p = (int **)malloc(sizeof(int *) * row);
* for (int i = 0; i < row; i++) {
* (*p)[i] = (int *)malloc(sizeof(int) * col);
* }
* }
*
* use:
* init_matrix(&matrix->matrix, matrix->row, matrix->col);
*/
/*
* 清理工作
*/
void clear_matrix(struct matrix *matrix)
{
for (int i = 0; i < matrix->row; i++) {
free(matrix->matrix[i]);
}
free(matrix->matrix);
}
void init_matrix_data(struct matrix *matrix)
{
for (int i = 0; i < matrix->row; i++) {
for (int j = 0; j < matrix->col; j++) {
matrix->matrix[i][j] = i*j;
}
}
}
void print_matrix(struct matrix *matrix)
{
printf("row = %d, col = %d\n", matrix->row, matrix->col);
for (int i = 0; i < matrix->row; i++) {
for (int j = 0; j < matrix->col; j++) {
printf("%d ", matrix->matrix[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[])
{
struct matrix *matrix = (struct matrix *)malloc(sizeof(struct matrix));
init_matrix(matrix, 5, 2);
init_matrix_data(matrix);
print_matrix(matrix);
clear_matrix(matrix);
return 0;
}
最大最小
linux-3.17.3/include/linux/kernel.h:
/*
* min()/max()/clamp() macros that also do
* strict type-checking.. See the
* "unnecessary" pointer comparison.
*/
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#define min3(x, y, z) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
typeof(z) _min3 = (z); \
(void) (&_min1 == &_min2); \
(void) (&_min1 == &_min3); \
_min1 < _min2 ? (_min1 < _min3 ? _min1 : _min3) : \
(_min2 < _min3 ? _min2 : _min3); })
#define max3(x, y, z) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
typeof(z) _max3 = (z); \
(void) (&_max1 == &_max2); \
(void) (&_max1 == &_max3); \
_max1 > _max2 ? (_max1 > _max3 ? _max1 : _max3) : \
(_max2 > _max3 ? _max2 : _max3); })
若 typeof
关键词不可用,可试试 __typeof__