数学上的乘法是对每一位都乘的。
除了用于scanf的,其他变量都应该初始化,否则结果会为固定随机值
大部分情况下需要输出换行符
scanf的第二个参数一定要传入指针,否则IDE不会报错,但是会SIGTERM
认真看给定输入数据的顺序与含义!!!
见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 | 从右边开始,把最后一个 |
x & (x - 1) |
100101000 -> 100100000 |
| 2 | 保留最右侧的 |
x & -x 或 x & (x ^ (x - 1))
|
100101000 -> 1000 |
| 3 | 去掉最后一位 | x >> 1 |
101101 -> 10110 |
| 4 | 取右数第 |
(x >> (k - 1)) & 1 |
1101101 -> 1, k = 4 |
| 5 | 取末尾 |
x & ((1 << k) - 1) |
1101101 -> 101, k = 3;1101101 -> 1101, k = 4
|
| 6 | 只保留右边连续的 |
(x ^ (x + 1)) >> 1 |
100101111 -> 1111 |
| 7 | 右数第 |
x ^ (1 << (k - 1)) |
101001 -> 101101, k = 3 |
| 8 | 在最后加一个 |
x << 1 |
101101 -> 1011010 |
| 9 | 在最后加一个 |
(x << 1) + 1 |
101101 -> 1011011 |
| 10 | 把右数第 |
x & ~(1 << (k - 1)) |
101101 -> 101001, k = 3 |
| 11 | 把右数第 |
x | (1 << (k - 1)) |
101001 -> 101101, k = 3 |
| 12 | 把右边起第一个 |
x | (x + 1) |
100101111 -> 100111111 |
| 13 | 把右边连续的 |
x | (x - 1) |
11011000 -> 11011111 |
| 14 | 把右边连续的 |
x & (x + 1) |
100101111 -> 100100000 |
| 15 | 把最后一位变成 |
x & ~1 |
101101 -> 101100 |
| 16 | 把最后一位变成 |
x | 1 |
101100 -> 101101 |
| 17 | 把末尾 |
x | ((1 << k) - 1) |
101001 -> 101111, k = 4 |
| 18 | 末尾 |
x ^ ((1 << k) - 1) |
101101 -> 101100, k = 1;101001 -> 100110, k = 4
|
涉及左移获取2^x时,使用1LL防止移动32及以上位溢出。
long double可能占用16字节,范围在-1.210^-4932~1.210^4932
格式化字符串为%Lf
后缀L:0.11112L
数组指针每次加(减) 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 位置 含义(谁不可改) 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 字典序小返回负值,两者一样返回 0,str1 字典序更大则返回正值。请注意,不要简单的认为返回值只有 0、1、-1 三种,在不同平台下的返回值都遵循正负,但并非都是 0、1、-1。
strcpy(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' 返回 str1。
strstr(char *str1, const char *str2):若 str2 是 str1 的子串,则返回 str2 在 str1 的首次出现的地址;如果 str2 不是 str1 的子串,则返回 NULL。
strchr(const char *str, int c):找到在字符串 str 中第一次出现字符 c 的位置,并返回这个位置的地址。如果未找到该字符则返回 NULL。
strrchr(const char *str, int c):找到在字符串 str 中最后一次出现字符 c 的位置,并返回这个位置的地址。如果未找到该字符则返回 NULL。