Skip to content

Micraow/BUAA-C-Program

Repository files navigation

血泪教训

乘法

数学上的乘法是对每一位都乘的。

变量初始化

除了用于scanf的,其他变量都应该初始化,否则结果会为固定随机值

输出

大部分情况下需要输出换行符

scanf

scanf的第二个参数一定要传入指针,否则IDE不会报错,但是会SIGTERM

认真看给定输入数据的顺序与含义!!!

用getchar清空缓存区

见snippets

浮点数运算

与浮点数有关的运算,整数最好也要加.0或强制转化为(double)

浮点数比较

见snippets

位运算优先级低于布尔运算

类似于 i & 1 == 0是错的,必须写成(i & 1) == 0

数据类型 大小估算

int: -2^31 ~ 2^31 或约上至2*10^9 long long: 10^18数量级

数根

所有位上的数字加起来,如果不是一位数则一直累加,最后得到一位整数称为数根

若n非9的倍数,数根为n%9 否则为9

位运算技巧

序号 操作描述 位运算表达式 示例
1 从右边开始,把最后一个 $1$ 改写成 $0$ x & (x - 1) 100101000 -> 100100000
2 保留最右侧的 $1$,其余清零 x & -xx & (x ^ (x - 1)) 100101000 -> 1000
3 去掉最后一位 x >> 1 101101 -> 10110
4 取右数第 $k$ (x >> (k - 1)) & 1 1101101 -> 1, k = 4
5 取末尾 $k$ x & ((1 << k) - 1) 1101101 -> 101, k = 3
1101101 -> 1101, k = 4
6 只保留右边连续的 $1$ (x ^ (x + 1)) >> 1 100101111 -> 1111
7 右数第 $k$ 位取反 x ^ (1 << (k - 1)) 101001 -> 101101, k = 3
8 在最后加一个 $0$ x << 1 101101 -> 1011010
9 在最后加一个 $1$ (x << 1) + 1 101101 -> 1011011
10 把右数第 $k$ 位变成 $0$ x & ~(1 << (k - 1)) 101101 -> 101001, k = 3
11 把右数第 $k$ 位变成 $1$ x | (1 << (k - 1)) 101001 -> 101101, k = 3
12 把右边起第一个 $0$ 变成 $1$ x | (x + 1) 100101111 -> 100111111
13 把右边连续的 $0$ 变成 $1$ x | (x - 1) 11011000 -> 11011111
14 把右边连续的 $1$ 变成 $0$ x & (x + 1) 100101111 -> 100100000
15 把最后一位变成 $0$ x & ~1 101101 -> 101100
16 把最后一位变成 $1$ x | 1 101100 -> 101101
17 把末尾 $k$ 位变成 $1$ x | ((1 << k) - 1) 101001 -> 101111, k = 4
18 末尾 $k$ 位取反 x ^ ((1 << k) - 1) 101101 -> 101100, k = 1
101001 -> 100110, k = 4

左移用 1LL

涉及左移获取2^x时,使用1LL防止移动32及以上位溢出。

特别大数用long double

long double可能占用16字节,范围在-1.210^-4932~1.210^4932

格式化字符串为%Lf

后缀L:0.11112L

判断整数用round (可以四舍五入)

strlen包含换行\n

数组指针与数组指针

数组指针每次加(减) 1,意味着指针位置向后(前)移动了整个数组空间的大小

int (*pa)[5] = &a;
float (*pb)[20] = &b;
char (*pc)[30] = &c;

数组指针这样定义

指针数组这样定义:

int *piarray[10];
float *pfarray[20];
double *pdarray[30];

这是因为[]优先级 高。

定义数组指针需要加()

指针函数 函数指针

指针函数: char *strstr(char *s, char *s1);

函数指针: int (*f_name) (…);

指针函数指针: int *(*p_name) (…);

const修饰

声明 const 位置 含义(谁不可改) int *p 无 const 指针可改,指向的数据也可改 const int *p * 左边 指向的数据不可改,指针可改 int *const p * 右边 指针不可改,指向的数据可改 const int *const p * 左右都有 指针不可改,指向的数据也不可改

快速记忆口诀:

左指数据,右指指针

(const 在 * 左边 → 限制数据;在右边 → 限制指针)

字符串标准库

C 标准库操作字符数组 char[]/const char*。

参见:fprintf、fscanf、空终止字节字符串

printf("%s", s): %s 来输出一个字符串字符数组)。
scanf("%s", &s): %s 来读入一个字符串字符数组)。
sscanf(const char *__source, const char *__format, ...):从字符串 __source 里读取变量比如 sscanf(str,"%d",&a)。
sprintf(char *__stream, const char *__format, ...): __format 字符串里的内容输出到 __stream 比如 sprintf(str,"%d",i)。
strlen(const char *str):返回从 str[0] 开始直到 '\0' 的字符数注意未开启 O2 优化时该操作写在循环条件中复杂度是 Θ(𝑁)
\Theta(N) strcmp(const char *str1, const char *str2):按照字典序比较 str1 str2  str1 字典序小返回负值两者一样返回 0str1 字典序更大则返回正值请注意不要简单的认为返回值只有 01-1 三种在不同平台下的返回值都遵循正负但并非都是 01-1strcpy(char *str, const char *src):  src 中的字符复制到 str str src 均为字符数组头指针返回值为 str 包含空终止符号 '\0'。
strncpy(char *str, const char *src, int cnt):复制至多 cnt 个字符到 str  src 终止而数量未达 cnt 则写入空字符到 str 直至写入总共 cnt 个字符strcat(char *str1, const char *str2):  str2 接到 str1 的结尾 *str2 替换 str1 末尾的 '\0' 返回 str1strstr(char *str1, const char *str2): str2  str1 的子串则返回 str2  str1 的首次出现的地址如果 str2 不是 str1 的子串则返回 NULLstrchr(const char *str, int c):找到在字符串 str 中第一次出现字符 c 的位置并返回这个位置的地址如果未找到该字符则返回 NULLstrrchr(const char *str, int c):找到在字符串 str 中最后一次出现字符 c 的位置并返回这个位置的地址如果未找到该字符则返回 NULL

About

我在学习BUAA C语言程序设计过程中写下的代码

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages