C语言语法

来源:互联网 发布:网络层的协议内容 编辑:程序博客网 时间:2024/05/23 02:07

C语言语法  即关键字的使用方法

1. 关键字介绍  如何处理01,内存意识

翻译器的目的是要把C程序翻译为一串01放于内存中,供CPU执行。而C的语法就是告诉翻译器如何翻译,所以一个优秀的C程序员,看到的只C的源代码,想到的应该是这串01应该怎么“玩”。你写出一行代码,它为你翻译为01,至于接下来这串01怎么玩,你随便(只要不越出操作系统的控制 )!

1. 关键字分类

a) 符号声明关键字    在机器中注册一个助记符

char / int / …… / float / void 告诉机器助记符关联的内存块的解释方式

struct / enum / union / typedef  定义一种新的内存块解释方式

b) 类型修饰关键字     01内存块的解释细节

short / long / unsigned / signed  只能修饰原生类型

c) 符号修饰关键字    如何获取助记符实体

* / & / [] / () / const / register / extern / volatile / static / restrict

d) 流程控制关键字

break else switch case return continue for default do if while

e) 机器信息获取关键字

sizeof / __LINE__ / __FILE__ /__STDC__ / __FUNC__ / __TIME__ / __DATE__

2. 变量符号实质   声明、定义、赋值

a) 定义一个符号name_a,翻译器会在符号表中加入一项记录 name_a 与 name_a关联的内存实体的地址,以便使用name_a时,可以得到name_a对应的 01

b) 声一个符号name_a,翻译器只会在符号表中加入name_a,但是空出 name_a关联的内存地址,以便在日后定义时填入。

c) 符号的赋值 name_a = name_b,就是将name_b关联的实体01拷贝到name_a关联的实体处。为了保证两块实体大小相同,机器要求name_aname_b相同类型(例外之处,两个指针或者char/int这些已知转化方式的数据赋值时,只是提出警告)。

3. 类型符号的使用  struct / union / enum  typedef

a) struct / union  使用现有类型组装一个新的内存块解释方式

b) enum 向机器注册数据符号,符号的关联值并不是内存址,而是符号的值。所以enum声明的符号只能表示常数int

c) typedef 符号反射为类型符号

struct A_t m;     struct A_t  A   A  m;    //两个m是等效的

int a[100];      typedef int A[100];       A a;     //两个a是等效的

4. 符号修饰关键字   extern / volatile / static / * / [] / const / restrict

a) extern / volatile / static  声明符号的

b) restrict 告知机器符号关联的内存不被其它指针指向,机器不检查。

  • void * memcpyvoid * restrict s1, const void * restrict s2, size_t n);
  • void * memove(void * s1, const void * s2, size_t n);

c) * 与 [] 的种种关系

1.  由int *a,b;  a为指针符号,b为变量符号,可知*的作用是修饰符号。“真正”的变量符号为*aa只是一个简单变量符号,它关联的内存中存储的值是“*a这个变量关联的地址。

2.  [] 声明助记符name_aname_a的关联值就是n个元素的内存实体的起始值,name_a的修饰为int[10]name_a在“=”右边时,认为是一个指针;当name_a在等号左边时认为是一个数组

3.  数组指针的运算  &name_a + 1 于 (int)(&name_a)+sizeof(name_a)

注,对于数组的这种表现只能说是翻译器作出的一种特殊的解释方式,不能用简单的符号表记录机制处理。

4. 数组与指针的复杂逻辑   修饰优先级 [] 高于 *

int *a[20]; a是一个数组,数组元素是int *;

int (*a)[20];  a是一个指针,指向的是一个int [20]的数组。 

d) * 与 () 的种种关系   其操作性与 [] 基本一致

  1. () 用来声明函数符号
  2. int fun();   sizeof(fun) == 1

e) const 常量符号

  1. int const *p   const 修饰的是 变量符号 *p p所指地址中的值不变
  2. int *const p   const 修饰的是 变量符号 p   p的值不变

5. 错综的关键字修饰分析  分离类型修饰与符号修饰后按优先级分析

Ø int *a[20] 与 int (*a)[20]    unsigned int *a[20]

Ø int (*const p)[20]  p是一个常量,且是一个指针,指向int[20]的地址块

Ø int *p()[];  p是一个函数,返回值为int*[]

Ø int *p[]();  p是一个数组,元素为int*() 返回int*函数

6. 传值调用 —— 本质是形参作为一个新符号(可能已被修饰),其值复制实参的关联值

1.  变量

int fun(int name_a)

fun (name_b); 调用时,将name_b关联的内存赋值给name_a

2.  指针

int fun(int *name_a)

fun (&name_b); 调用时,将&name_b关联的内存赋值给*name_a

3.  数组

int fun( int a[20]);

fun(b);  实际上是调用 b = a; 见上面分析,a以指针做右值

2. 机器特性

1. 精度问题,浮点数计算不可结合。

2. int 长度为32,将int转型后的指针在64位机上可能会出错。

3. 语法特性

1.  计算基于32(64位机为64)运行,加载原符号关联的内存值入寄存器,扩展/截断为机器位长。类型关键字(尤其是类型修饰关键字)价值只是告诉编译器如何进行位长处理)。

2.  数据比较操作

1.  int 之间默认以无符号比较;  sint sint 以有符号比较

2.  短符号间比较,若存在singed符号,以有符号扩展后比较

3.  不同长度,若存在uint 以无符号比较。

3.  浮点数表示


 

0 0
原创粉丝点击