C语言的发展历史大致上分为三个阶段:Old Style C、C89和C99。Ken Thompson和Dennis Ritchie最初发明C语言时有很多语法和现在最常用的写法并不一样,但为了向后兼容性(Backward Compatibility),这些语法仍然在C89和C99中保留下来了。C89是最早的C语言规范,于1989年提出,1990年首先由ANSI(美国国家标准委员会,American National Standards Institute)推出,后来被接纳为ISO国际标准(ISO/IEC 9899:1990),因而有时也称为C90,最经典的C语言教材[K&R]就是基于这个版本的,C89是目前最广泛采用的C语言标准,大多数编译器都完全支持C89。C99标准(ISO/IEC 9899:1999)是在1999年推出的,加入了许多新特性,但目前仍没有得到广泛支持,在C99推出之后相当长的一段时间里,连gcc也没有完全实现C99的所有特性。
1 |
|
1 | cc hello.c |
1 | cl -GX hello.c |
1 | ./a.out |
1 | a.exe |
访问main函数的返回值的方式和系统有关,不论UNIX还是Windows系统,执行程序后,必须发出一个适当的echo
命令。
1 | $ echo $? |
1 | echo %ERRORLEVEL% |
注释以字符 /*
开始, 以 */
结束。注释不能够嵌套,也不能够出现在字符串字面值或字符字面值中。
有的C代码中有类似 // comment
的注释,两个/
斜线(Slash)表示从这里直到该行末尾的所有字符都属于注释,这种注释不能跨行,也不能穿插在一行代码中间。这是从C++借鉴的语法,在C99中被标准化。
_
被看作是字母,通常用于命名较长的变量名,以提高可读性。C99规定的关键字有:
auto | break | case | char | const |
continue | default | do | double | |
else | enum | extern | float | for |
goto | if | inline | int | long |
register | restrict | return | short | signed |
sizeof | static | struct | switch | typedef |
union | unsigned | void | volatile | while |
_Bool | _Complex | _Imaginary | ||
+
、-
、*
、/
、%
(取模运算符);%
不能应用于float或double类型;+
和-
具有相同的优先级,它们的优先级比*
、/
和%
的优先级低,而运算符*
、/
和%
的优先级又比一元运算符+
和-
的优先级低。算数运算符采用从左到右的结合规则。关系运算符包括下列几个运算符:
>
、>=
、<
、<=
它们具有相同的优先级。优先级仅次于它们的是相等性运算符:
==
、!=
关系运算符的优先级比算术运算符低 。因此,表达式 i < lim-1
等价于 i < (lim - 1)
。
逻辑运算符&&
与||
有一些较为特殊的属性,由&&
与||
连接的表达式按从左到右的顺序进行求值,并且,在知道结果值为真或为假后 立即停止运算 。逻辑运算符优先级:&&
比||
的优先级高,但两者都比关系运算符和相等性运算符的优先级低。
++n
先将n的值递增1,然后再使用变量n的值。n++
则是先使用变量n的值,然后再将n的值递增1。例:标准函数strcat(s,t)
,它将字符串t连接到字符串s的尾部。
1 | /* strcat: concatenate t to end of s; s must be big enough */ |
C语言提供了6个位操作运算符。这些运算符只能作用于整型操作数,即只能作用于带符号或无符号char、short、int、long类型:
运算符 | 作用 |
---|---|
& |
按位与(AND) |
| |
按位或(OR) |
^ |
按位异或(XOR) |
<< |
左移 |
>> |
右移 |
~ |
按位求反(一元运算符) |
按位与运算符&通常用于屏蔽某些二进制位,例如:
1 | n = n & 0177; |
该语句将n中除7个低二进制位外的其他各位均置为0。
按位或运算符|
常用于将某些二进制位置为1,例如:
1 | x = x | SET_ON; |
该语句将x中对应于 SET_ON
中为1的那些二进制位置为1。
例如:函数getbits(x,p,n)
,它返回x中从右边数第p位开始向右数n位的字段。
1 | /* getbits: get n bits from position p */ |
1 | expr1 ? expr2 : expr3 |
应该注意,如果expr2
与expr3
的类型不同,结果的类型也将进行转换。例如,如果f
为float类型,n
为int类型,那么表达式 (n > 0) ? f : n
是float类型,与n是否为正值无关 。
运算符的优先级与结合性[1]
运算符 | 结合性 |
---|---|
() [] -> . |
从左至右 |
! ~ ++ -- + - * (type) sizeof |
从右至左 |
* / % |
从左至右 |
+ - |
从左至右 |
<< >> |
从左至右 |
< <= > >= |
从左至右 |
== != |
从左至右 |
& |
从左至右 |
^ |
从左至右 |
| |
从左至右 |
&& |
从左至右 |
|| |
从左至右 |
?: |
从右至左 |
= += -= /= ^= &= ^= |= <<= >>= |
从右至左 |
, |
从右至左 |
一元运算符+
、-
、&
与*
比相应的二元运算符+
、-
、&
与*
的优先级高。 ↩︎