C核心 那些个关键字
概述 - C语言老了
目前而言(2017年5月12日) C语言中有 32 + 5 + 7 = 44 个关键字. 具体如下 O(∩_∩)O哈哈~
-> C89关键字
char | short | int | unsigned |
long | float | double | struct |
union | void | enum | signed |
const | volatile | typedef | auto |
register | static | extern | break |
case | continue | default | do |
else | for | goto | if |
return | switch | while | sizeof |
-> C99新增关键字
_Bool | _Complex | _Imaginary | inline | restrict |
-> C11新增关键字
_Alignas | _Alignof | _Atomic | _Generic | _Noreturn | _Static_assert | _Thread_local |
下面容我细细分析起具体用法.(存在平台差异, 有问题特别欢迎评论补充, 这就相当于一个关键字字典)
C89 32个关键字
1) char
解释:
声明变量的时候用! char占1字节, 8bit. 多数系统(vs or gcc)上是有符号的(arm 上无符号), 范围是[-128, 127].
在工程项目开发中推荐用
- #include <stdint.h>
- int8_t -> signed char
- uint8_t -> unsigned char
扯淡一点, 程序开发最常遇到的就是自解释问题. 鸡生蛋, 蛋生鸡. 后面再分析 signed 和 unsigned
演示:
- #include <stdio.h>
- char c;
- c = getchar();
- rewind(stdin);
- printf("c = %d, c = %c.\n", c);
2) short
解释:
声明变量的时候用! short 占2字节, 为无符号的. 默认自带signed. 范围[-2^15, 2^15 - 1] 2^15 = 32800.
推荐使用 int16_t or uint16_t 类型.
演示:
- short port = ;
- printf("port = %d.\n", port);
3) int
解释:
声明变量的时候用! int 声明的变量, 占4字节, 有符号. 范围 [-2^31, 2^31-1].
推荐用 int32_t 和 uint32_t类型开发. 方便移植
演示:
- int hoge = ;
- printf("hoge = %d.\n", hoge);
4) unsigned
解释:
变量类型修饰符! 被修饰的变量就是无符号的.范围 >= 0. unsigned 只能修饰整型的变量.
当然当你用这个修饰变量的时候. 再使用 - 和 -- 运算的时候一定要小心
演示:
- unsigned int i = ; // 正确
- unsigned short s = ; // 正确
- unisgned float f = 0.11f; // 错误
5) long
解释:
声明变量的时候用!长整型 x86上四字节, x64上8字节. 一定不比int字节数少. C99之后出现long long类型8字节.
演示:
- long l = ;
- long long ll = l;
- printf("l = %ld, ll = %lld.\n", l, ll);
6) float
解释:
声明变量的时候用! 四字节. 精度是6-7位左右. 详细精度可以看 float与double的范围和精度
演示:
- float f = -0.12f; // 四字节
- long float lf = ; // 八字节 等同于 double, 不推荐这么写
7) double
解释:
声明变量的时候用!八字节,精度在15-16位左右.有的时候压缩内存用float代替.
演示:
- double d = 2e13; // 8字节
- long double ld = -0.99; // x86也是8字节, 不推荐这么用
- long long double lld = ; // 写法错误, 不支持
8) struct
解释:
定义结构体, 这个关键字用法广泛, 是大头. c 的重要思路就是面向过程编程. 撑起面向过程的大头就是结构体.
struct 就是定义结构的东西, 可以看看下面演示
演示:
- // 普通结构体定义
- struct node {
- int id;
- struct node * next;
- };
- struct node node = { , NULL };
- // 匿名结构定义
- struct {
- int id;
- char * name;
- } per = { , "王志" };
9) union
解释:
定义公用体, 用法很花哨. 常在特殊库函数封装中用到.技巧性强
演示:
- // 普通定义
- union type {
- char c;
- int i;
- float f;
- };
union type t = { .f = 3.33f };- // 匿名定义
- union { ... } t = { .... };
- // 类型匿名定义
- struct cjson {
- struct cjson * next; // 采用链表结构处理, 放弃二叉树结构, 优化内存
- struct cjson * child; // type == ( _CJSON_ARRAY or _CJSON_OBJECT ) 那么 child 就不为空
- unsigned char type; // 数据类型和方式定义, 一个美好的意愿
- char * key; // json内容那块的 key名称
- union {
- char * vs; // type == _CJSON_STRING, 是一个字符串
- double vd; // type == _CJSON_NUMBER, 是一个num值, ((int)c->vd) 转成int 或 bool
- };
- };
再来一种 union用法, 利用内存对齐.
- //12.0 判断是大端序还是小端序,大端序返回true
- inline bool
- sh_isbig(void) {
- static union {
- unsigned short _s;
- unsigned char _c;
- } _u = { };
- return _u._c == ;
- }
还有很久以前利用union 实现内存字节对齐, 太多了. 每个关键字用法, 确实很多, 很意外.
10) void
解释:
这个是空关键字. 用法很多. 也是我最喜欢的关键字. 用在函数声明中, 类型定义中.
演示:
- // 函数声明
- extern void foo();
- // 函数参数约束
- extern void foo(void); // ()中加了void表示函数是无参的, 否则是任意的
- // 万能类型定义, 指针随便转
- void * arg = NULL;
11) enum
解释:
枚举类型, C中枚举类型很简陋. 其实就相当于一种变相的INT宏常量. 估计这也许也是 INT宏常量和枚举并存的原因.
演示:
- //
- // flag_e - 全局操作基本行为返回的枚举, 用于判断返回值状态的状态码
- // >= 0 标识 Success状态, < 0 标识 Error状态
- //
- typedef enum {
- Success_Exist = +, //希望存在,设置之前已经存在了.
- Success_Close = +, //文件描述符读取关闭, 读取完毕也会返回这个
- Success_Base = +, //结果正确的返回宏
- Error_Base = -, //错误基类型, 所有错误都可用它, 在不清楚的情况下
- Error_Param = -, //调用的参数错误
- Error_Alloc = -, //内存分配错误
- Error_Fd = -, //文件打开失败
- } flag_e;
枚举变量完全可以等同于 int 变量使用, 枚举值等同于宏INT常量使用. 枚举的默认值是以1位单位从上向下递增.
12) signed
解释:
变量声明类型修饰符. 有符号型, 对比 unsigned 无符号型. 变量声明默认基本都是 signed, 所以多数别人就省略了.
演示:
- signed int piyo = 0x1314520;
- signed char * str = u8"你好吗";
当然了, 平时不需要刻意加. 会让人嫌麻烦. O(∩_∩)O哈哈~
13) const
解释:
const修饰的变量表示是个不可修改的量. 和常量有点区别. 可以简单认为 const type val 是个只读的.
演示:
- // 声明不可修改的量
- const int age = ;
- // 修饰指针
- const int * pi = NULL; // *pi 不能修改指向变量
- int * const pt = NULL; // pt 不能指向新的指针
- const int * const pc = NULL; // *pc 和 pc 都不能动
其实在c中基本没有什么改变不了的. 全是内存来回搞, 软件不行硬件~~
14) volatile
解释:
声明变量修饰符, 可变的. 当变量前面有这个修饰符. 编译器不再从寄存器中取值, 直接内存读取写入. 保证实时性.
常用在多线程代码中.
演示:
- // 具体轮询器
- struct srl {
- mq_t mq; // 消息队列
- pthread_t th; // 具体奔跑的线程
- die_f run; // 每个消息都会调用 run(pop())
- volatile bool loop; // true表示还在继续
- };
以后使用loop的时候, 其它线程修改, 当前线程也能正确获取它的值.
15) typedef
解释:
类型重定义修饰符. 重新定义新的类型.
演示:
- // 声明普通类型
- typedef void * list_t;
- // 声明不完全类型, 头文件中不存在struct tree
- typedef struct tree * tree_t;
16) auto
解释:
变量类型声明符, auto变量存放在动态存储区,随着生命周期{开始 }结束而立即释放.存放在栈上.
默认变量都是auto的. 基本都是不写, 除非装逼!
演示:
- {
- // 生存期开始
- int hoge = ;
- auto int piyo = ;
- // 生存期结束
- }
不要用生命周期结束的变量, 存在各种意外.
17) register
解释:
变量修饰符,只能修饰整形变量.表示希望这个变量存放在CPU的寄存器上.现代编译器在开启优化时候,
能够一定程度上默认启用register寄存器变量.
演示:
- #include <limits.h>
- register int i = 0;
while (i < INT_MAX) {- ++i;
}
由于CPU寄存器是有限的, 有时候你哪怕声明的寄存器变量也可能只是普通变量. printf("&i = %p\n", &i) 这种用法是非法.
寄存器变量不能取地址.
18) static
解释:
static 用法很广泛. 修饰变量, 表示变量存在于静态区, 基本就是全局区. 生存周期同系统生存周期.
static修饰的变量作用域只能在当前文件范围内. 可以看成上层语言的private. 除了auto就是static.
static修饰函数表示当前函数是私有的,只能在当前文件中使用. 更加详细的看演示部分.
演示:
- // 修饰全局变量, 只对当前文件可见
- static int _fd = ;
- // 修饰局部变量, 存储在全局区, 具有记忆功能
- {
- static int _cnt = ;
- }
- // 修饰函数, 函数只能在当前文件可见
- static void * _run(void * arg) {
- ......
- return arg;
- }
- //
- // C99之后加的static新用法, 编译器优化
- // static 只能修饰函数第一维,表示数组最小长度, 方便编译器一下取出所有内存进行优化
- //
- int sum(int a[static ]) { ... }
19) extern
解释:
extern 关键字表示声明, 变量声明, 函数声明. 奇葩的用法很多.
演示:
- // 声明引用全局变量
- extern int g_cnt;
- // 声明引用全局函数
- extern int kill(int sig, int val);
当然有时候extern不写, 对于变量不行会出现重定义. 对于函数是可以缺省写法. 再扯一点
- // extern 主动声明, 希望外部可以调用
- extern int kill(int sig, int val);
- // extern 缺省,不推荐外部调用
- int kill(int sig, int val);
20) break
解释:
结束语句. 主要用于循环的跳转, 只能跳转到当前层级. 也用于switch 语句中, 跳出switch嵌套.
演示:
- for(;;) {
- // 符合条件跳转
- if(six == )
- break;
- }
- // break 跳出while循环
- int i = ;
- while(i < ) {
- if(i == )
- break;
- }
break用法主要和循环一块使用, 还有do while. 但只能跳转当前层循环.
21) case
解释:
switch 语句中分支语句. 确定走什么分支.
演示:
- // case 普通用法 和 break成对出现
- switch ((c = *++ptr)) {
- case 'b': *nptr++ = '\b'; break;
- case 'f': *nptr++ = '\f'; break;
- case 'n': *nptr++ = '\n'; break;
- case 'r': *nptr++ = '\r'; break;
- case 't': *nptr++ = '\t'; break;
- }
多扯一点, 对于case相当于标记点. switch 中值决定case跳转到哪里.再一直往下执行, 遇到break再结束switch嵌套.
22) continue
解释:
跳过此次循环. 直接进行条件判断操作. for 和 while 有些局别. for 会执行第三个后面的语句.
演示:
- // for 循环 continue
- for(int i = ; i < ; ++i) {
- if(i % == )
- continue;
- // 上面continue 调到 ++i -> i < 20 代码块
- }
23) default
解释:
switch 分支的默认分支, 假如case都没有进入那就进入default分支. default 可以省略break. c 语法中可行.
演示:
- uint32_t
- skynet_queryname(struct skynet_context * context, const char * name) {
- switch(name[]) {
- case ':':
- return strtoul(name+,NULL,);
- case '.':
- return skynet_handle_findname(name + );
- default:
- skynet_error(context, "Don't support query global name %s",name);
- }
- return ;
- }
24) do
解释:
do 循环. 先执行循环体, 后再执行条件判断.
演示:
- register i = ;
- do {
- if(i % == )
- continue;
- printf("i = %d.\n", i);
- } while(++i < );
do while 循环有时候可以减少一次条件判断. 性能更好, 代码更长.
25) else
解释:
else 是 if 的反分支. 具体看演示
演示:
- #include <stdbool.h>
- if(true) {
- puts("你好吗?");
- }
- else {
- puts("我们分手吧.");
- }
- // 附赠个else 语法
- #if defined(__GNUC__)
- // 定义了 __GNUC__ 环境, 就是gcc环境
- #else
- #error "NOT __GNUC__, NEED GCC!";
- #enfif
26) for
解释:
for 循环其实就是while循环的语法糖. 也有独到的地方.
演示:
- for(int i = ; i < ; ++i) {
- if(i == )
- continue;
- if(i == )
- break;
- }
- 等价于下面这个
- int i = ;
- while(i < ) {
- if(i == ) {
- ++i;
- continue;
- }
- if(i == )
- break;
- ++i;
- }
- // for 最好的写法, 在于死循环写法
- for(;;) {
- // xxxx
- }
for(;;) { } 比 while(true) { } 写法好, 有一种不走条件判断的意图, 虽然汇编代码是一样的.
27) goto
解释:
goto 是我第二喜欢的关键字. 可以在当前函数内跳转. goto 可以替代所有循环.
演示:
- __loop:
- // xxx 死循环用法
- goto __loop;
- __exitloop:
还有就是在工程开发中, goto 常用于复制的业务逻辑.
- if ((n = *tar) == '\0') // 判断下一个字符
- goto __err_ext;
- if(cl % rl){ // 检测 , 号是个数是否正常
- __err_ext:
- SL_WARNING("now csv file is illegal! c = %d, n = %d, cl = %d, rl = %d."
- , c, n, cl, rl);
- return false;
- }
28) if
解释:
if 分支语句. 用法太多了. 程序语句中分支就是智能.
演示:
- if(false) {
- puts("我想做个好人!");
- }
29) return
解释:
程序返回语句太多了. 用于函数返回中. 返回void 直接 return;
演示:
- #include <stdlib.h>
- int main(int argc, char * argv[]) {
- return EXIT_SUCCESS;
- }
30) switch
解释:
条件分支语句. 很复杂的if else if 时候可以switch.
演示:
- #include <unistd.h>
- do {
- int rt = write(fd, buf, sizeof buf)
- if(rt < ) {
- switch(errno) {
- case EINTER
- continue;
- default:
- perror("write error");
- }
- }
- } while(rt > );
31) while
解释:
循环语句, 有do while 和 while 语句两种.
演示:
- #define _INT_CNT (10)
- int i = -;
- while(++i < _INT_CNT) {
- // ......
- }
32) sizeof
解释:
这个关键字也称为 sizeof 运算符. 计算变量或类型的字节大小. 这个关键字特别好用!
演示:
- sizeof (main) -> x86 上四字节
- // 获取数组长度,只能是数组类型或""字符串常量,后者包含'\0'
#define LEN(arr) (sizeof(arr) / sizeof(*(arr)))
到这里C89保留的关键字基本解释完毕.
C99 5个新增关键字
33) _Bool
解释:
bool类型变量, 等价于 unsigned char . 只有0和1.
演示:
- #include <stdbool.h>
- bool flag = true;
- // 或者直接用
- _Bool flag = !;
34) _Complex
解释:
对于C99 标准定义, 存在 float _Complex, double _Complex, long double _Complex 复数类型. 下面先演示gcc 中关于复数的用法.
演示:
- #include <math.h>
- #include <stdio.h>
- #include <complex.h>
- //
- // 测试 c99 complex 复数
- //
- int main(int argc, char * argv[]) {
- float complex f = -1.0f + .0if;
- printf("The complex number is: %f + %fi\n",crealf(f), cimagf(f));
- double complex d = csqrt(4.0 + .0i);
- printf("d = %lf + %lfi\n", creal(d), cimag(d));
- return ;
- }
其实在复数类型中, gcc标准实现
- #define complex _Complex
而在VS 中实现具体为
- #ifndef _C_COMPLEX_T
- #define _C_COMPLEX_T
- typedef struct _C_double_complex
- {
- double _Val[];
- } _C_double_complex;
- typedef struct _C_float_complex
- {
- float _Val[];
- } _C_float_complex;
- typedef struct _C_ldouble_complex
- {
- long double _Val[];
- } _C_ldouble_complex;
- #endif
- typedef _C_double_complex _Dcomplex;
- typedef _C_float_complex _Fcomplex;
- typedef _C_ldouble_complex _Lcomplex;
总的而言, 学习C 最好的平台就是 *nix 平台上使用 Best new GCC. 当然除了科学计算会用到复数, 其它很少.
这里VS 和 GCC实现不一样. 用起来需要注意.
35) _Imaginary
解释:
虚数类型. _Complex 复数类型的虚部. 例如 10.0i, 10.8if 等等. 这个关键字在VS 上没有实现. 其实我也觉得没有必要.
和_Complex有重叠.
演示:
这个关键字无法在代码中表示. 系统保留, 我们不能使用.
36) inline
解释:
内联函数,从C++中引入的概念. 就是将小函数直接嵌入到代码中. C的代码损耗在于函数的进出栈. 要是可以推荐用内联函数
替代宏. 宏能不用就不用. 函数声明的时候不要加inline 需要加extern, 定义的时候需要加inline.
演示:
- /*
- * 对json字符串解析返回解析后的结果
- * jstr : 待解析的字符串
- */
- extern cjson_t cjson_newtstr(tstr_t str);
- inline cjson_t
- cjson_newtstr(tstr_t str) {
- str->len = _cjson_mini(str->str);
- return _cjson_parse(str->str);
- }
- // 还有就是和static 一起使用
- static inline int _sconf_acmp(tstr_t tstr, struct sconf * rnode) {
- return strcmp(tstr->str, rnode->key);
- }
37) restrict
解释:
这是很装逼的关键字用于编译器优化. 关键字restrict只用于限定指针;该关键字用于告知编译器,
所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;
这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。
演示:
- extern void *mempcpy (void *__restrict __dest,
- const void *__restrict __src, size_t __n)
- __THROW __nonnull ((, ));
上面是摘自GCC 的 string.h中. 其实正式用法
- // 简单演示用法, GCC 和 VS 都是 __restrict 推荐加在 * 后面
- static void _strlove(char * __restrict dest) {
- *dest = '\0';
- }
Pelles C 编译器可以完整支持 restrict.
C11 7个新增关键字
38) _Alignas
解释:
内存对齐的操作符. 需要和_Alignof配合使用, 指定结构的对齐方式.
演示:
- #ifndef __cplusplus
- #define alignas _Alignas
- #define alignof _Alignof
- #define __alignas_is_defined 1
- #define __alignof_is_defined 1
- #endif
例如一种用法
- #include <stdio.h>
- #include <stdalign.h>
- struct per {
- int age;
- double secl;
- char sex;
- };
- int main(int argc, char * argv[]) {
- char c[];
- alignas(struct per) struct per * per = (struct per *)&c;
- printf("per = %p, c = %p.\n", per, c);
- return ;
- }
将c 数组以 struct per 对齐方式对齐返回回去.
39) _Alignof
解释:
得到类型和变量的对齐方式.
演示:
- printf("alignof(struct per) = %zd.\n", alignof(struct per));
40) _Atomic
解释:
原子操作, 原子锁. gcc 很早就支持. 详细用法可以参照 CAS https://sanwen8.cn/p/18dZQie.html
讲的可以.
演示:
- #include <stdio.h>
- #include <stdatomic.h>
- int main(int argc, char * argv[]) {
- _Atomic int hoge = ATOMIC_VAR_INIT();
- int piyo = atomic_load(&hoge);
- printf("piyo = %d.\n", piyo);
- piyo += ;
- atomic_store(&hoge, piyo);
- printf("hoge = %d.\n", hoge);
- return ;
- }
具体的执行结果, 你也懂就那样. 原子操作, 对于写出高效代码很重要.
41) _Generic
解释:
这个比较叼, C的泛函机制. 高级函数宏. 下面来个老套路用法
演示:
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #define ABS(x) \
- _Generic((x), int:abs, float:fabsf, double:fabs)(x)
- //
- // 测试 C11 语法
- //
- int main(int argc, char * argv[]) {
- int a = , b = , c = ;
- _Generic(a + 0.1f, int:b, float:c, default:a)++;
- printf("a = %d, b = %d, c = %d\n", a, b, c);
- printf("int abs: %d\n", ABS(-));
- printf("float abs: %f\n", ABS(-12.04f));
- printf("double abs: %f\n", ABS(-13.09876));
- return EXIT_SUCCESS;
- }
宏泛型真的很给力. 宏又能玩上天了.
42) _Noreturn
解释:
修饰函数,绝对不会有返回值. _Noreturn 声明的函数不会返回. 引入此新的函数修饰符有两个目的:
- 消除编译器对没有 return的函数的警告.
- 允许某种只针对不返回函数的优化.
演示:
- _Noreturn void suicide(void) {
- abort(); // Actually, abort is _Noreturn as well
- }
再扯一点, GCC中等同于 __attribute__((__noreturn__)), 在VC中相似功能是 __declspec(noreturn).
它不是说函数没有返回值,而是说一旦你调了这个函数,它永远不会返回。一些函数是永远不会返回的,
比如 abort或者 exit之类,调用它们就意味着结束程序. 所以 warning就显得没有必要.
43) _Static_assert
解释:
编译器期间断言, 当 #if #error 搞完毕(预编译)之后, 编译器断言. assert是运行时断言.用的时候看具体的需求.
演示:
- _Static_assert(__STDC_VERSION__ >= 201112L, "C11 support required");
- // Guess I don't really need _Static_assert to tell me this :-(
44) _Thread_local
解释:
到这里快扯完了, 其实C11标准是个很好的尝试. 为C引入了线程和原子操作. 各种安全特性补充. 可以说C强大了.
但是还远远不够, 因为越来越丑了. C11为C引入了线程 在 头文件<threads.h>中定义.但也允许编译可以不实现.
_Thread_local是新的存储类修饰符, 限定了变量不能在多线程之间共享。
演示:
- _Thread_local static int i;
- // Thread local isn't local!
语义上就是线程的私有变量.
后记 - 我们也不年轻了
如果有问题欢迎补充, 关键字当字典用也是好的 哈哈啊
真正男子汉 http://music.163.com/#/m/song?id=31421394&userid=16529894
你会心痛吗, 已经心痛了 /(ㄒoㄒ)/~~
C核心 那些个关键字的更多相关文章
- JS魔法堂:ES6新特性——GeneratorFunction介绍
一.前言 第一次看koajs的示例时,发现该语句 function *(next){...............} ,这是啥啊?于是搜索一下,原来这是就是ES6的新特性Generator ...
- PHP的学习--生成器Generators
生成器总览 (PHP 5 >= 5.5.0, PHP 7) 生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低. 生成器允 ...
- 【转】还html标签以本来意义
说句实话,“div+css”这个词汇不知道害了多少人,也许其提出者本意并没有错,但是跟风者从表现曲解了其意思,认为整个页面就应当是div+css文件的组合.这样做,对于视觉上并没有什么影响,因为还原了 ...
- robotframework笔记23
远程库接口 远程库接口提供了对在测试库 比机器人框架本身是在不同的机器上运行, 同时实现图书馆使用其他语言比 本机支持Python和Java. 为一个测试库用户远程 library看起来几乎一样的其他 ...
- android 模拟抢红包 原理
Android微信抢红包外挂 源代码 标签: 微信 抢红包 外挂 插件 2015-02-20 22:59 30211人阅读 评论(16) 收藏 举报 分类: Android(58) 版权声明:本文 ...
- 9.python的布尔类型与流程控制
布尔类型其实可以算是一种特殊的数字,下面是 help() 函数得到的帮助信息: Help on class bool in module __builtin__: class bool(int) | ...
- 你知道HTML标签设计的本意吗? 把HTML标签用到该用的地方去
"DIV+CSS"这个词汇不知道害了多少人,也许其提出者本意并没有错,但是跟风者从表现曲解了其意思,认为整个页面就应当是DIV+CSS文件的组合.这样做,对于视觉上并没有什么影响, ...
- python的布尔类型与流程控制
布尔类型其实可以算是一种特殊的数字,下面是 help() 函数得到的帮助信息: bool 首先,请注意这一行:
- PHP 生成器语法
一般你在迭代一组数据的时候,需要创建一个数据,假设数组很大,则会消耗很大性能,甚至造成内存不足. //Fatal error: Allowed memory size of 1073741824 by ...
随机推荐
- python中深copy,浅copy
版权声明:本文为博主原创文章,未经博主允许不得转载. >>> mylist1 = [1, 2, 3, 4] >>> myl = mylist1 >>&g ...
- 【题解】Atcoder ARC#83 E-Bichrome Tree
哈哈~自己做出来的E题!(虽然这题被机房大佬强D极水).最开始神经错乱,写了个完全不对的贪心,竟然只错了4个点(。•ˇ‸ˇ•。) 可以发现,一个节点的子树内部和他颜色相同的节点权值和 是固定的,那么不 ...
- [洛谷P4550]收集邮票
题目大意:有$n(n\leqslant10^4)$个物品,第$i$次会从这$n$个物品中随机获得一个,并付出$i$的代价,问获得所有的$n$个物品的代价的期望. 题解:令$f_i$表示现在已经获得了$ ...
- Kindle 电子书相关的工具软件【转】
这里是与 Kindle 电子书相关的工具软件.它们可以帮助我们解决在日常使用电子书时所可能遇到的问题,比如 kindle 管理工具.kindle 转换工具.kindle电子书制作工具.kindle 推 ...
- Linux环境下用Weblogic发布项目【二】 -- 配置Domain域
配置注意事项: 修改密码时密码长度最少8位:在"<下一步>"后面为空即表示敲回车: 具体配置步骤如下: [root@GPS-App ~]# [root@GPS-App ...
- UIViewContentMode的各种效果
UIViewContentMode的各种效果: 首先它是枚举类型的数据,表示为下所示: typedef enum { UIViewContentModeScaleToFill, ...
- 微服务学习三:springboot与springcloud集成之Eurake的使用(server端,client端)
这个多亏了网站上的一个大神的博客: http://blog.csdn.net/forezp/article/details/70148833 强烈推荐学习: 1.springcloud是什么,这个大家 ...
- Leetcode 485. 最大连续1的个数
1.题目描述(简单题) 给定一个二进制数组, 计算其中最大连续1的个数. 示例 1: 输入: [1,1,0,1,1,1] 输出: 3 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 ...
- Java的位运算符—与(&)、非(~)、或(|)、异或(^)
位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...
- HDU2031 进制转换
#include <iostream> #include "string" #include "cstdio" #include "cst ...