From 7fb146b52a4f47ff8ba4c58dcaadb733810947d9 Mon Sep 17 00:00:00 2001 From: jaywcjlove Date: Wed, 12 Oct 2022 17:20:35 +0000 Subject: [PATCH] feat: add `c.md` cheatsheet. 7db43897083d851bddf089ae251d6f095309e157 --- docs/c.html | 1054 +++++++++++++++++++++++++++++++++++++++++++++++ index.html | 3 + style/style.css | 11 +- 3 files changed, 1067 insertions(+), 1 deletion(-) create mode 100644 docs/c.html diff --git a/docs/c.html b/docs/c.html new file mode 100644 index 00000000..e5d48b41 --- /dev/null +++ b/docs/c.html @@ -0,0 +1,1054 @@ + + + + +C 备忘清单 + & c cheatsheet & Quick Reference + + + + + + +

C 备忘清单

+

提供基本语法和方法的 C 快速参考备忘单。

+

入门

+

hello.c

+ +
#include <stdio.h>
+
+int main() {
+  printf("Hello World!");
+  return 0;
+}
+
+

使用 gcc 编译 hello.c 文件

+
$ gcc -o hello hello.c
+
+

运行编译后的二进制文件(hello)

+
$ ./hello
+# 输出 => Hello World
+
+

变量

+ +
int myNum = 15;
+
+int myNum2; // 不赋值,然后再赋值
+myNum2 = 15;
+
+int myNum3 = 15;  // myNum3 值为 15
+myNum3 = 10;      // 现在 myNum3 值为 10
+
+float myFloatNum = 5.99; // 浮点数
+char myLetter = 'D';     // 字符串
+
+int x = 5;
+int y = 6;
+int sum = x + y;  // 添加变量相加
+// 声明多个变量
+int x = 5, y = 6, z = 50;
+
+

常量 Constants

+
const int minutesPerHour = 60;
+const float PI = 3.14;
+
+

最佳实践

+
const int BIRTHYEAR = 1980;
+
+

注释

+
// 这是一个注释
+printf("Hello World!"); // 这是一个注释
+/* 多行注释,上面的代码将打印出 Hello World!
+到屏幕上,真是太棒了 */
+
+

打印文本

+
printf("I am learning C.");
+int testInteger = 5;
+printf("Number = %d", testInteger);
+
+float f = 5.99; // 浮点数
+printf("Value = %f", f);
+
+short a = 0b1010110;  // 2 进制数字
+int b = 02713;        // 8 进制数字
+long c = 0X1DAB83;    // 16 进制数字
+
+// 以 8 进制形似输出
+printf("a=%ho, b=%o, c=%lo\n", a, b, c);
+// 输出 => a=126, b=2713, c=7325603
+
+// 以 10 进制形式输出
+printf("a=%hd, b=%d, c=%ld\n", a, b, c);
+// 输出 => a=86, b=1483, c=1944451
+
+// 以 16 进制形式输出(字母小写)
+printf("a=%hx, b=%x, c=%lx\n", a, b, c);
+// 输出 => a=56, b=5cb, c=1dab83
+
+// 以 16 进制形式输出(字母大写)
+printf("a=%hX, b=%X, c=%lX\n", a, b, c);
+// 输出 => a=56, b=5CB, c=1DAB83
+
+

控制空格数

+
int a1=20, a2=345, a3=700;
+int b1=56720, b2=9999, b3=20098;
+int c1=233, c2=205, c3=1;
+int d1=34, d2=0, d3=23;
+
+printf("%-9d %-9d %-9d\n", a1, a2, a3);
+printf("%-9d %-9d %-9d\n", b1, b2, b3);
+printf("%-9d %-9d %-9d\n", c1, c2, c3);
+printf("%-9d %-9d %-9d\n", d1, d2, d3);
+
+

输出结果

+
20        345       700  
+56720     9999      20098
+233       205       1    
+34        0         23   
+
+

%-9d 中,d 表示以 10 进制输出,9 表示最少占 9 个字符的宽度,宽度不足以空格补齐,- 表示左对齐

+

字符串 Strings

+
char greetings[] = "Hello World!";
+printf("%s", greetings);
+
+

访问字符串

+
char greetings[] = "Hello World!";
+printf("%c", greetings[0]);
+
+

修改字符串

+
char greetings[] = "Hello World!";
+greetings[0] = 'J';
+
+printf("%s", greetings);
+// 输出 "Jello World!"
+
+

另一种创建字符串的方法

+
char greetings[] = {'H','e','l','l','\0'};
+
+printf("%s", greetings);
+// 输出 "Hell!"
+
+

C 没有 String 类型,使用 char 类型并创建一个字符 array

+

条件判断

+ +
int time = 20;
+if (time < 18) {
+  printf("再会!");
+} else {
+  printf("晚上好!");
+}
+// 输出 -> "晚上好!"
+int time = 22;
+if (time < 10) {
+  printf("早上好!");
+} else if (time < 20) {
+  printf("再会!");
+} else {
+  printf("晚上好!");
+}
+// 输出 -> "晚上好!"
+
+

三元运算符

+ +
int time = 20;
+(time < 18) ? printf("再会!") : printf("晚上好!");
+
+

Switch

+
int day = 4;
+
+switch (day) {
+  case 3: printf("周三"); break;
+  case 4: printf("周四"); break;
+  default:
+    printf("期待周末");
+}
+// 输出 -> "周四" (day 4)
+
+

While 循环

+
int i = 0;
+
+while (i < 5) {
+  printf("%d\n", i);
+  i++;
+}
+
+

注意:不要忘记增加条件中使用的变量,否则循环永远不会结束,成为“死循环”!

+

Do/While 循环

+
int i = 0;
+
+do {
+  printf("%d\n", i);
+  i++;
+} while (i < 5);
+
+

For 循环

+
int i;
+
+for (i = 0; i < 5; i++) {
+  printf("%d\n", i);
+}
+
+

跳出循环 Break/Continue

+ +
int i;
+
+for (i = 0; i < 10; i++) {
+  if (i == 4) {
+    break;
+  }
+  printf("%d\n", i);
+}
+
+

i 等于 4 时跳出循环

+
int i;
+
+for (i = 0; i < 10; i++) {
+  if (i == 4) {
+    continue;
+  }
+  printf("%d\n", i);
+}
+
+

示例跳过 4 的值

+

While Break 示例

+
int i = 0;
+
+while (i < 10) {
+  if (i == 4) {
+    break;
+  }
+  printf("%d\n", i);
+  i++;
+}
+
+

While continue 示例

+
int i = 0;
+
+while (i < 10) {
+  i++;
+  if (i == 4) {
+    continue;
+  }
+  printf("%d\n", i);
+}
+
+

数组 Arrays

+ +
int myNumbers[] = {25, 50, 75, 100};
+printf("%d", myNumbers[0]);
+// 输出 25
+
+

更改数组元素

+
int myNumbers[] = {25, 50, 75, 100};
+myNumbers[0] = 33;
+
+printf("%d", myNumbers[0]);
+
+

循环遍历数组

+
int myNumbers[] = {25, 50, 75, 100};
+int i;
+
+for (i = 0; i < 4; i++) {
+  printf("%d\n", myNumbers[i]);
+}
+
+

设置数组大小

+
// 声明一个由四个整数组成的数组:
+int myNumbers[4];
+// 添加元素
+myNumbers[0] = 25;
+myNumbers[1] = 50;
+myNumbers[2] = 75;
+myNumbers[3] = 100;
+
+

枚举 Enum

+ +
enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
+
+

定义枚举变量

+
enum week a, b, c;
+
+enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c;
+
+

有了枚举变量,就可以把列表中的值赋给它

+
enum week { Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
+enum week a = Mon, b = Wed, c = Sat;
+// 或者
+enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat;
+
+

枚举示例应用

+
enum week {Mon = 1, Tues, Wed, Thurs} day;
+
+scanf("%d", &day);
+
+switch(day){
+  case Mon:   puts("Monday"); break;
+  case Tues:  puts("Tuesday"); break;
+  case Wed:   puts("Wednesday"); break;
+  case Thurs: puts("Thursday"); break;
+  default:    puts("Error!");
+}
+
+

用户输入

+
// 创建一个整数变量来存储我们从用户那里得到的数字
+int myNum;
+
+// 要求用户输入一个数字
+printf("请输入一个数字: \n");
+
+// 获取并保存用户输入的号码
+scanf("%d", &myNum);
+
+// 输出用户输入的数字
+printf("您输入的数字: %d", myNum);
+
+

用户输入字符串

+
// 创建一个字符串
+char firstName[30];
+// 要求用户输入一些文本
+printf("输入您的名字: \n");
+// 获取并保存文本
+scanf("%s", firstName);
+// 输出文本
+printf("Hello %s.", firstName);
+
+

内存地址

+

创建变量时,会为该变量分配一个内存地址

+
int myAge = 43;
+
+printf("%p", &myAge);
+// 输出:0x7ffe5367e044
+
+

要访问它,请使用引用运算符 (&)

+

创建指针

+
int myAge = 43;      // 一个 int 变量
+printf("%d", myAge); // 输出 myAge(43)的值
+
+// 输出 myAge 的内存地址(0x7ffe5367e044)
+printf("%p", &myAge);
+
+

指针变量

+ +
int myAge = 43;            // 一个 int 变量
+int* ptr = &myAge;         // 名为 ptr 的指针变量,用于存储 myAge 的地址
+
+printf("%d\n", myAge);     // 输出 myAge (43) 的值
+
+printf("%p\n", \&myAge);   // 输出 myAge 的内存地址(0x7ffe5367e044)
+
+printf("%p\n", ptr);       // 用指针(0x7ffe5367e044)输出myAge的内存地址
+
+

取消引用

+
int myAge = 43;     // 变量声明
+int* ptr = &myAge;  // 指针声明
+
+// 参考:用指针输出 myAge 的
+// 内存地址(0x7ffe5367e044)
+printf("%p\n", ptr);
+// 取消引用:用指针输出 myAge 的值 (43)
+printf("%d\n", *ptr);
+
+

运算符

+

算术运算符

+
int myNum = 100 + 50;
+int sum1 = 100 + 50;    // 150 (100 + 50)
+int sum2 = sum1 + 250;  // 400 (150 + 250)
+int sum3 = sum2 + sum2; // 800 (400 + 400)
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorNameDescriptionExample
+将两个值相加x + y
-从另一个值中减去一个值x - y
*将两个值相乘x * y
/将一个值除以另一个x / y
%取模返回除法余数x % y
++增量将变量的值增加 1++
--乘量将变量的值减 1--x
+

赋值运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
符号示例如同
=x = 5x = 5
+=x += 3x = x + 3
-=x -= 3x = x - 3
*=x *= 3x = x * 3
/=x /= 3x = x / 3
%=x %= 3x = x % 3
&=x &= 3x = x & 3
|=x |= 3x = x | 3
^=x ^= 3x = x ^ 3
>>=x >>= 3x = x >> 3
<<=x <<= 3x = x << 3
+

比较运算符

+
int x = 5;
+int y = 3;
+
+printf("%d", x > y);
+// 返回 1(真),因为 5 大于 3
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
符号名称示例
==等于x == y
!=不等于x != y
>大于x > y
<小于x < y
>=大于或等于x >= y
<=小于或等于x <= y
+

比较运算符用于比较两个值

+

逻辑运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
符号名称说明示例
&&逻辑如果两个语句都为真,则返回真x < 5 && x < 10
||逻辑如果其中一个语句为真,则返回真x < 5 || x < 4
!逻辑反转结果,如果结果为真则返回假!(x < 5 && x < 10)
+

运算符示例

+ +
unsigned int a = 60; /* 60 = 0011 1100 */  
+unsigned int b = 13; /* 13 = 0000 1101 */
+int c = 0;           
+
+c = a & b;      /* 12 = 0000 1100 */ 
+printf("Line 1 - c 的值是 %d\n", c );
+
+c = a | b;      /* 61 = 0011 1101 */
+printf("Line 2 - c 的值是 %d\n", c );
+c = a ^ b;      /* 49 = 0011 0001 */
+printf("Line 3 - c 的值是 %d\n", c );
+c = ~a;         /*-61 = 1100 0011 */
+printf("Line 4 - c 的值是 %d\n", c );
+c = a << 2;     /* 240 = 1111 0000 */
+printf("Line 5 - c 的值是 %d\n", c );
+c = a >> 2;     /* 15 = 0000 1111 */
+printf("Line 6 - c 的值是 %d\n", c );
+
+

位运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符描述实例
&按位与操作,按二进制位进行"与"运算(A & B) 将得到 12 即为 0000 1100
|按位或运算符,按二进制位进行"或"运算(A | B) 将得到 61 即为 0011 1101
^异或运算符,按二进制位进行"异或"运算(A ^ B) 将得到 49 即为 0011 0001
~取反运算符,按二进制位进行"取反"运算(~A) 将得到 -61 即为 1100 0011
<<二进制左移运算符A << 2 将得到 240 即为 1111 0000
>>二进制右移运算符A >> 2 将得到 15 即为 0000 1111
+

数据类型 Data Types

+

基本数据类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数据类型大小 Size范围 Range描述 Description
char1 字节−128 ~ 127单个字符/字母/数字/ASCII
signed char1 字节−128 ~ 127-
unsigned char1 字节0 ~ 255-
int24 字节−32,768 ~ 32,767存储整数
signed int2 字节−32,768 ~ 32,767
unsigned int2 字节0 ~ 65,535
short int2 字节−32,768 ~ 32,767
signed short int2 字节−32,768 ~ 32,767
unsigned short int2 字节0 ~ 65,535
long int4 字节-2,147,483,648 ~ 2,147,483,647
signed long int4 字节-2,147,483,648 ~ 2,147,483,647
unsigned long int4 字节0 ~ 4,294,967,295
float4 字节
double8 字节
long double10 字节
+

数据类型

+
// 创建变量
+int myNum = 5;             // 整数
+float myFloatNum = 5.99;   // 浮点数
+char myLetter = 'D';       // 字符串
+// 高精度浮点数据或数字
+double myDouble = 3.2325467;
+// 打印输出变量
+printf("%d\n", myNum);
+printf("%f\n", myFloatNum);
+printf("%c\n", myLetter);
+printf("%lf\n", myDouble);
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数据类型说 明
char字符型
short短整型
int整型
long长整型
float单精度浮点型
double双精度浮点型
void无类型
+

基本格式说明符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
格式说明符数据类型
%d%iint 整数
%ffloat 单精度的十进制类型
%lfdouble 高精度浮点数据或数字
%cchar 字符
%s用于 strings 字符串
+

基本格式说明符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
shortintlong
8 进制%ho%o%lo
10 进制%hd%d%ld
16 进制%hx / %hX%x / %X%lx / %lX
+

数据格式示例

+
int myNum = 5;
+float myFloatNum = 5.99; // 浮点数
+char myLetter = 'D';     // 字符串
+// 打印输出变量
+printf("%d\n", myNum);
+printf("%f\n", myFloatNum);
+printf("%c\n", myLetter);
+
+

预处理器

+

预处理器指令

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指令描述
#define定义宏
#include包含一个源代码文件
#undef取消已定义的宏
#ifdef如果宏已经定义,则返回真
#ifndef如果宏没有定义,则返回真
#if如果给定条件为真,则编译下面代码
#else#if 的替代方案
#elif如果 #if 条件为假,当前条件为
#endif结束一个 #if……#else 条件编译块
#error当遇到标准错误时,输出错误消息
#pragma使用标准化方法,向编译器发布特殊的命令到编译器中
+
// 所有的 MAX_ARRAY_LENGTH 替换为 20
+#define MAX_ARRAY_LENGTH 20
+// 系统库中获取 stdio.h
+#include <stdio.h>
+// 本地目录中获取 myheader.h
+#include "myheader.h"
+#undef  FILE_SIZE
+#define FILE_SIZE 42 // 取消已定义并定义为 42
+
+

预定义宏

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
描述
__DATE__当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量
__TIME__当前时间,一个以 "HH:MM:SS" 格式表示的字符常量
__FILE__这会包含当前文件名,一个字符串常量
__LINE__这会包含当前行号,一个十进制常量
__STDC__当编译器以 ANSI 标准编译时,则定义为 1
+ +

ANSI C 定义了许多宏,您可以使用这些宏,但是不能直接修改这些预定义的宏

+

预定义宏示例

+
#include <stdio.h>
+
+int main() {
+  printf("File :%s\n", __FILE__);
+  printf("Date :%s\n", __DATE__);
+  printf("Time :%s\n", __TIME__);
+  printf("Line :%d\n", __LINE__);
+  printf("ANSI :%d\n", __STDC__);
+}
+
+

宏延续运算符(\)

+

一个宏通常写在一个单行上。

+
#define  message_for(a, b)  \
+    printf(#a " 和 " #b ": 我们爱你!\n")
+
+

如果宏太长,一个单行容纳不下,则使用宏延续运算符 \

+

字符串常量化运算符(#)

+
#include <stdio.h>
+
+#define  message_for(a, b)  \
+  printf(#a " 和 " #b ": 我们爱你!\n")
+
+int main(void) {
+  message_for(Carole, Debra);
+  return 0;
+}
+
+

当上面的代码被编译和执行时,它会产生下列结果:

+
Carole 和 Debra: 我们爱你!
+
+

需要把一个宏的参数转换为字符串常量时,使用字符串常量化运算符 #

+

标记粘贴运算符(##)

+
#include <stdio.h>
+
+#define tokenpaster(n) printf ("token" #n " = %d", token##n)
+
+int main(void){
+  int token34 = 40;
+  tokenpaster(34);
+  return 0;
+}
+
+

defined() 运算符

+
#include <stdio.h>
+
+#if !defined (MESSAGE)
+   #define MESSAGE "You wish!"
+#endif
+
+int main(void) {
+  printf("Here is the message: %s\n", MESSAGE);  
+  return 0;
+}
+
+

参数化的宏

+
int square(int x) {
+   return x * x;
+}
+
+

宏重写上面的代码,如下:

+
#define square(x) ((x) * (x))
+
+

宏名称和左圆括号之间不允许有空格

+
#include <stdio.h>
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+int main(void) {
+   printf("Max between 20 and 10 is %d\n", MAX(10, 20));  
+   return 0;
+}
+
+

另见

+ +
+ diff --git a/index.html b/index.html index 10a40b34..5fb6cd96 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,9 @@ Bash + + +C diff --git a/style/style.css b/style/style.css index f5861d68..3a2e6642 100644 --- a/style/style.css +++ b/style/style.css @@ -465,11 +465,20 @@ a.text-grey { color: rgb(148 163 184/1); } -body:not(.home) .h2wrap > h2 a::after { +body:not(.home) .h2wrap > h2 a::after, body:not(.home) .h3wrap > h3 a::after { content: '#'; padding-right: 0.5rem; color: rgb(16 185 129/1); } +body:not(.home) .h3wrap > h3 a::after { + position: absolute; + left: -18px; + font-size: 1rem; + display: none; +} +body:not(.home) .h3wrap > h3:hover a::after { + display: initial; +} .wrap-header.h3wrap { z-index: 0;