开篇废话:

本文意在回顾 C 语言中的关键字,整理文件发现当时做的这些笔记还是蛮用心的,有临摹

前辈的足迹也有自己的理解和体会。时至今日2018已经跨过一半,对不起过去半年,今天

拿这篇关键字开篇,开启自己的程序猿心路,主要记录一下自己遇到的问题和学习的经历,

方便自己。如果能对别也有用那就更开心了,由于自己还很菜,理解和体会都很有限,如

果你打开发现了错误还请不吝赐教,随便评论,不要客气,我都会很感激的。首篇废话就

这么多吧,我可能废话比较多,哈哈,批评我吧~

C 关键字

/**
* 到目前C语言中有32+5+7=44个关键字,具体如下:
*
* ->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,多数系统上是有符号的(arm 上无符号)
范围 [-128, 127] 在工程项目中开发推荐用
int8_t -> singned char
uint8_t -> unsigned char
*/
char c = 'p'; /*
2) short 解释:
声明变量的时候用,short占2个字节,为无符号的,默认自带signed
范围[-2^15, 2^15-1]2^15 = 32800 推荐使用 int16_t or uint16_t 类型
*/
short port = 8080; /*
3) int
解释:
声明变量的时候用,int声明的变量占4个字节,有符号,范围[-2^31,2^31-1]2^31 推荐使用:int32_t or uint32_t 类型开发,方便移植
*/
int i = 0; /*
4) unsigned
解释:
变量类型修饰符,被修饰的变量就是无符号的,范围>=0,unsigned 只能修饰整型的变量
当然你用这个修饰变量的时候,再使用++和--运算的时候一定要小心。
*/
unsigned int i = 0; //正确
unsigned short s = 0; //正确
unsigned float f = 0.11f; //错误 /*
5) long
解释:
声明变量的时候使用,长整型x86上4个字节,x64上8个字节,一定不比int字节数少
c99之后出现long long 类型为8个字节
*/
long l = 4;
long long ll = 8; /*
6) float
解释:
声明变量的时候用,4个字节,精度是6-7位,
详细精度可以看:https://blog.csdn.net/dxy612/article/details/5518477
*/
float f = -0.12f; /*
7) double
解释:
声明变量的时候用,8个字节,精度在15-16位左右,有的时候压缩内存用float代替
*/
double d = 2e13; /*
8) struct
解释:
定义结构体,这个关键字用法很广,是大头。C的重要的思路就是面向过程编程,
撑起面向过程的大头就是结构体。
*/
// 普通结构体
struct node {
int id;
struct node *next;
};
struct node n = {1,NULL}; // 匿名结构体
struct {
int id;
char* name;
} per = {2,"Tom"}; /*
9) union
解释:
定义共用体,用法很花哨,常在特殊库函数封装中用到,技巧很强
*/
// 普通定义
union type {
char c;
int i;
float f;
};
union type t = {.f = 3.33f}; // 匿名定义
union {...} t = {...}; //类型匿名定义
struct cjson {
struct cjson *next; //采用链表结构处理,放弃二叉树结构,优化内存 unsigned char type; // 数据类型和方式定义,一个美好的愿望
char *key; // json内容那块的key名称
union {
char *vs; // type == _CJSON_STRING, 是一个字符串
double vd; // type == _CJSON_NUMBER, 是一个num值((int)c->vd)转成int或bool
};
}; /*
什么是大小端? Endian表示数据在存储器中的存放顺序, 大端(Big Endian): 是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的
高地址中,这样的存储模式有点儿类似把数据当做字符串顺序处理:地址由小向大增加,
儿数据从高位往低位。 小端(Little Endian): 是指数据的高字节保存在内存的高地址中,而数据的低字节保存在
内存的低地址中,这种存储模式将地址的高低和数据位权有效的结合起来,高地址部分权值
高,低地址部分权值低,和我们的逻辑方法一致。 这两种模式,泥瓦匠记忆宫殿:“小端低低”。这样就知道小端的模式,反之大端的模式。 https://www.cnblogs.com/Alandre/p/4878841.html
*/ // 在来一种union用法,判断大小端,笔试题中长见
inline bool
sh_isbig(void)
{
static union {
unsigned short s;
unsigned char c;
}U = {1}; // 1 -> 0x0001;
return U.c == 0;
} /*
10) void
解释:
这个关键字用法很多,也是用在函数声明中,或函数参数
*/
// 函数声明
extern void foo(); // 函数参数约束
extern void foo(void); //函数参数为void表示函数是无参数的,否则是任意的 // 万能类型定义,指针随便转
void* vp = NULL; /*
11) enum
解释:
枚举类型,C中枚举类型很简陋,相当于一种变相的INT宏常量,估计也许是INT宏
常量和枚举并存的原因 问题1
有些面试题中会问你enum 和#define 的区别:
1. #define 宏常量是在预编译阶段进行简单的替换;enum常量则是在编译的时候确定其值
2. 一般在调试器里,可以调试枚举常量,但不是不能调试宏常量。
3. 枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。 问题2
1. 枚举能做的事,#define 宏能不能做到?如果能,那为什么还需要枚举?
答:能,枚举可以自增1,这样不用每一个值都定义,而宏必须每个值都定义,
而枚举是一个集合,代表一类值,像代码中的颜色归为一类方便使用,而#define不能形成集合 2. sizeof(ColorVal)的值是多少?为什么?
enum Color{
GREEN = 1,
RED,
BLUE,
GREEN_RED = 10,
GREEN_BLUE
}ColorVal; 答:值为4,ColorVal一个枚举变量,而枚举变量代表一个整数。 */
//
// flag_e -全局操作基本行为返回的枚举,用于判断返回值状态的状态码
// >=0 标识Success状态,< 0 标识Error状态
//
// 枚举变量完全可以等同于int变量使用,枚举值等同于宏INT常量使用,枚举的默认值
// 是以1为单位从上向下递增。
//
typedef enum {
Success_Exit =2, //希望存在,设置之前已经存在了
Success_Close =1, //文件描述符读取关闭,读取完毕也返回这个
Success_Base =0, // 结果正确的返回宏 Error_Base =-1, //错误类型,所有错误都用它,在不清楚的情况下
Error_Parm =-2, //调用参数错误
Error_Alloc =-3, //内存分配错误
Error_Fd =-4, //文件打开失败
} flag_e; /*
12) signed
解释:
变量声明类型修饰符,有符号型,对比unsigned无符号型,变量声明默认基本都是
singned ,所有多数别就省略了
*/
signed int piyo = 0x12345678; /*
13) const
解释:
const 修饰的变量表示是一个不可修改的量,和常量有点区别,
*/
// 声明不可修改的量
const int age = 24; // 修饰指针
const int *pa = NULL; //pa指向的值(*pa)是不能修改
int *const pt = NULL; //pt不能指向新的指针,pt指向的值(*pt)可以修改
const int *const pc = NULL; //pc和pc指向的值(*pc)都不能修改 /*
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; // 重定义变量类型
typedef unsigned long int ub4; /* unsigned 4-byte quantities*/
typedef unsigned char ub1; /* unsigned 1-byte quantities*/ // 定义一个函数指针
typedef uint32_t (*crc_func)(uint32_t crc, const void *buf, size_t len);
// 使用
crc_func crc32c; //声明一个crc_func类型的变量,实际就是一个函数指针,指向函数的首地址 /*
16) auto
解释:
变量类型声明符,auto变量存放在动态存储区,随和声明周期{开始},结束而立即释放,存在在栈上 默认变量都是auto的,基本是不写
*/
//演示
{
// 生存期开始
int a = 0;
auto int p = 1;
// 生存期结束
} /*
17) register
解释:
修饰变量,这个关键字请求编译器尽可能的将变量存放在CPU内部寄存器中而不是通过内存寻址访问
以提高效率,注意是尽可能,不是绝对。 实用register修饰的注意点
虽然寄存器的速度非常快 ,但是实用register修饰符也要些限制的,register变量必须是能被cpu寄存器所能接受的类型
意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度,而且register变量
可能不存在在内存中,所以不能用取地址运算符"&"来获取register变量的地址。
*/
#include <limits.h> register int i = 0;
while (i < INT_MAX) {
++i;
} /*
18) static
解释:
static用法很广,修饰变量,函数,从字面上看static 很安静,这个关键字在C++
中做了扩展,在C语言中重要就前面提到的两个作用。 1. 修饰变量
变量又分为局部变量和全局变量,但它们都在内存的静态区。 静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用extern声明也没有办法使用
准确的说:作用域是从定义之处开始,到文件结尾处结束, 静态局部变量:在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他函数也
用不了,由于被static修饰的变量总是存在内存的静态区,所有即使这个函数运行结束,这个
静态变量的值也不会被销毁,函数下次使用时任然能用这个值。 看下面一段代码: static int j;
void fun1(void) {
static int i = 0;
i++;
} void fun2(void) {
j = 0;
j++;
} int main()
{
int k = 0;
for(k = 0; k < 10; k++) {
fun1();
fun2();
} return 0;
} 此时i和j的值分别是多少?
我们来分析一下哈:
首先毫无疑问,j 是个全局静态变量,调用一次fun2()后,它的值始终没有变,所有调用10次值还是1 i这个变量是一个局部静态变量,值存放在内存的静态区,调用一次fun1()结束后它的值不会被销毁,
函数下次调用的时候任然使用这个值,所有调用10次它的值一次为,1,2,3,4,5,6,7,8,9,10,11 2. 修饰函数
函数前面加static使得函数成为静态函数,但此处"static"的含义不是指存储方式,而是指对函数作用域
仅局限于本文件(所有称内部函数)使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义
的函数是否会与其他文件中的函数同名。 // C99之后加的static新用法,编译器优化
/ static 只能修饰函数第一维,表示数组最小长度,方便编译器一下取出所有内存进行优化
*/
int sum(int a[static 10]) { ... } /*
19) extern
解释:
extern (外面的,外来的)可以置于变量或函数前,以表明变量或函数的定义在别的文件中
下面代码用到的这些变量或函数是外来的,不是本文件中定义的,提示连接器遇到此变量
和函数时在其他模块中解析/绑定此标识符。
*/ // 声明引用全局变量
extern int G_arg; // 声明引用全局函数,(主动声明,希望外部可以调用)
extern int kill(int sig, int val); // 当然有时候extern不写,对于变量不写会出现重定义,对于函数时可以缺省的 /*
20) break
解释:
结束语句,主要用于循环的跳出,只能跳出到当前层级,也用于switch语句中
跳出swithc嵌套
*/
// 演示 for循环
for(;;) {
// 符合条件跳转
if(n == 10)
break; // 跳出for循环
} /*
21) 22) 23) switch & case & default
解释:
21)switch :条件分支语句,很复杂的if else if时候可以用switch
22)case : 语句中分支语句,确定走哪个分支
23)default: switch 分支的默认分支,所有case都没有进入就到default分支
*/
// 演示 switch (errcode) {
case SSL_ERROR_ZERO_RETURN:
/* Possibly a clean shutdown. */
if (SSL_get_shutdown(bev_ssl->ssl) & SSL_RECEIVED_SHUTDOWN)
event = BEV_EVENT_EOF;
else
dirty_shutdown = 1;
break;
case SSL_ERROR_SYSCALL:
/* IO error; possibly a dirty shutdown. */
if ((ret == 0 || ret == -1) && ERR_peek_error() == 0)
dirty_shutdown = 1;
break;
case SSL_ERROR_SSL:
/* Protocol error. */
break;
case SSL_ERROR_WANT_X509_LOOKUP:
/* XXXX handle this. */
break;
case SSL_ERROR_NONE:
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_ACCEPT:
default:
/* should be impossible; treat as normal error. */
event_warnx("BUG: Unexpected OpenSSL error code %d", errcode);
break;
} /*
24) continue
解释:
跳过此次(本轮)循环,直接进行条件判断操作,进入下一轮循环,
for和while循环有些区别,for会执行第三个后面的语句
*/
// 演示
for(int i = 0; i < 20; ++i) {
if(i % 2 == 0)
continue; // 满足if跳到 ++i,再到条件 i<20
} /*
25) do ... 26) while 27) for
解释:
C 语言中的三种循环
25) do: do循环,先执行循环体,在执行条件判断,先保证循环体执行一遍在判断条件
在一个菜单的程序设计的时候用do...while 比较好,首先给出选择。 26) while: 循环,先判断while后的条件,只有条件真才执行里面的代码块,
常用的还有就是一种死循环的写法 while(1) 27) for: 循环,for循环很容易的控制循环次数,多用于事先知道循环次数的情况下
*/
// 演示
/* do -while 循环 */
do {
event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
xcount++;
} while (count != fired); /* while 循环 */
while(1) {
if('#' == GetInputChar())
break;
} /* for 循环 */
for (i = 0; i < 25; i++) {
tv = run_once();
if (tv == NULL)
exit(1);
fprintf(stdout, "%ld\n",
tv->tv_sec * 1000000L + tv->tv_usec);
} /*
28) if ... 29) else
解释:
28) if: if分支语句,可以单独使用,可嵌套
29) else: else分支,必须和if分支对应,和if分支条件相反
*/
n = recv(fd, (char*)&ch, sizeof(ch), 0);
if (n >= 0)
count += n;
else
failures++;
if (writes) {
if (widx >= num_pipes)
widx -= num_pipes;
n = send(pipes[2 * widx + 1], "e", 1, 0);
if (n != 1)
failures++;
writes--;
fired++;
} /*
30) goto
解释:
关于goto这个关键字,褒贬很多,原因就在于它太自由,可以灵活的跳转,在结构化
编程中它有了很多争议,如果不加以限制,它的自由跳转的确会破坏结构化设计的风格
所有使用它一定要慎重,下面我们用一段真实代码展示它的魅力, */
// 演示
if (evbuffer_expand_fast_(buf, to_alloc, 2) < 0) {
goto done;
} for (n = 0; n < n_vec; n++) {
/* XXX each 'add' call here does a bunch of setup that's
* obviated by evbuffer_expand_fast_, and some cleanup that we
* would like to do only once. Instead we should just extract
* the part of the code that's needed. */ if (evbuffer_add(buf, vec[n].iov_base, vec[n].iov_len) < 0) {
goto done;
} res += vec[n].iov_len;
} done:
EVBUFFER_UNLOCK(buf);
return res; /*
31) return
解释:
return 用来终止一个函数并返回其后面跟着的值 使用return 不可返回指向“栈内存”的“指针”,因为该内存在函数体结束后就被自动释放了
*/
// 演示 #include <stdio.h> int main(int arg, char* argv[]) {
...... return EXIT_SUCCESS;
} /*
32) sizeof
解释:
也称为sizeof运算符,计算变量或类型的字节大小,它常被误认为是个函数
面试中也经常有它出现,下面我们看看它的用法
*/
// 演示 x86上
int *p = NULL;
sizeof(p) 的值是多少 ---> 4
sizeof(*p)呢? ---> 4 int a[100];
sizeof(a)的值是多少 ---> 400
sizeof(a[100])的值 ---> 4
sizeof(&a)的值 ---> 4
sizeof(&a[0])的值 ---> 4 int b[100];
void func(int b[100]) {
sizeof(b); // sizeof(b)的值 ---> 4
} // 常用一种写法获取数组长度
#define LEN(arr) (sizeof(arr) / sizeof(*(arr)))
#define LEN(arr) (sizeof(arr) / sizeof(arr[0]))

到此 C89 的32个关键字都就介绍完了,对于 C99 和 C11的关键字,后续完善.....

后记

《意颓废》

意颓废,人难寐。
夜夜长街空买醉。
路茫茫,断离肠。
梦牵魂索,独守西窗,伤!伤!伤 。

花儿碎,风流泪。
曲悲弦断连心肺。
恋成殇,心透凉。
一朝白头,只为情狂,怆!怆!怆。

回首C语言关键字(~回首向来萧瑟处~)的更多相关文章

  1. NOIP2018 Day0 回首向来萧瑟处,也无风雨也无晴

    回首向来萧瑟处,也无风雨也无晴 NOIP2018 Day0 感想  by HGOI ljc20020730 Back ground: /* HGOI 陈功杰让我们写初赛总结?! (考这么烂还要写总结? ...

  2. 1.C语言关键字(auto break case char const swtich)

    ANSI C标准C语言共有32个关键字,分别为: auto break case char const continue default do double else enum extern floa ...

  3. FILE不是C语言关键字

    FILE不是C语言关键字,只是标准C中的标准输入输出中定义的一个新的数据类型 stdio.htypedef struct _iobuf{ char* _ptr; int _cnt; char* _ba ...

  4. 李洪强漫谈iOS开发[C语言-009] - C语言关键字

    // //  main.m //  04 - C语言关键字 // //  Created by vic fan on 16/7/12. //  Copyright © 2016年 李洪强. All r ...

  5. C语言关键字-volatile

    1.C语言关键字volatile     C 语言关键字volatile(注意它是用来修饰变量而不是上面介绍的__volatile__)表明某个变量的值可能在外部被改变,因此对这些变量的存取 不能缓存 ...

  6. c语言关键字总结

    1.关键字变更历史 1999年12月16日,ISO推出了C99标准,该标准新增了5个C语言关键字: inline restrict _Bool _Complex _Imaginary(注意bool 从 ...

  7. C/C++ 知识点---C语言关键字(32个)

    C/C++ 知识点 1.C语言关键字(32个) <1>.基本数据类型 [5] void :声明函数无返回值或无参数,声明空类型指针 char :声明字符型变量 int :声明整形变量 fl ...

  8. 执行Go程序的三种方式及Go语言关键字

    执行 Go 程序的三种方式及 Go 语言关键字 执行 Go 程序的三种方式 一.使用 go run 命令 二.使用 go build 命令 Step1. 对 go 源码源文件执行 go build 命 ...

  9. 继续学习:C语言关键字

    auto :声明自动变量 break:跳出当前循环 case:开关语句分支 char :声明字符型变量或函数 const :声明只读变量 continue:结束当前循环,开始下一轮循环 default ...

随机推荐

  1. ThinkPhp3.2.3 多项目 后台 APP接口设计 框架设计

    ↓↓↓项目文件组成部分↓↓↓ APP文件是后台,index.php是入口文件 Interface文件是接口,注意这里不要用api命名!可能会有问题!interface.php是入口文件 注:两个入口文 ...

  2. Spark中文文本分析建模

    实用的朴素贝叶斯模型建模 建模过程主要是把文本转化成向量然后再作分析 数据格式: ,善良 美丽 ,丑陋 阴险 卑鄙 ,温和 ....... 注:前面是给文章贴的标签,后面是文章的分词,分词可以找关于分 ...

  3. java多线程(六)

    使用Runnable接口创建线程 Runnable接口 只有一个run()方法 Thread类实现了Runable接口 便于多个线程共享资源 Java不支持多继承,如果已经继承了某个基类,便要实现Ru ...

  4. Singapore retailer will release this adidas NMD R1

    Select spots are restocking the adidas NMD Singapore this Friday, Feb 24th featuring three different ...

  5. 1 - bootstrap基本模板

    bootstrap 3.x 下载地址:http://v3.bootcss.com/ 基本模板如下: <!DOCTYPE html> <html lang="zh-cn&qu ...

  6. poj1329 Circle Through Three Points

    地址:http://poj.org/problem?id=1329 题目: Circle Through Three Points Time Limit: 1000MS   Memory Limit: ...

  7. web前端基础补充

    1  布局和事件 布局效果如下(标题和内容都居中,两边留空白) 布局代码如下 <!DOCTYPE html> <html lang="en"> <he ...

  8. 20145311王亦徐 实验三 "敏捷开发与XP实践"

    20145311王亦徐 实验三 "敏捷开发与XP实践"程序设计过程 实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 git 上传代码 查看代码是否有修 ...

  9. hbase(三)coprocessor

    介绍 coprocessor这个单词看起来很神秘,直译为协处理器,其实可以理解成依赖于regionserver进程的辅助处理接口. hbae在0.92版本之后提供了coprocessor接口.目前hb ...

  10. IIS 7.5 配置 php 5.4.22 链接 sql 2008(用PDO链接数据库)

    最近在接触PHP这块,关于在wndows系统下的php配置,虽然网上已经很多文章,但有时候有些配置找起也麻烦,所以分享给大家. 一.php 5.4.22 下载地址 http://windows.php ...