C 语言基础

  • 关键字 while typedef

  • 运算符 =-*/% ++ --

  • 语句,表达式,序列点

  • 类型转换

  • 带参数的函数

  • 各种循环 while for

  • 分支跳转

基本运算符

=+-*/

%

++ 的前缀递增和后缀递增

--

关于优先级。++ -- 的优先级非常高,比这两高的只有 ()

其他运算符

sizeofsize_t

C 语言规定 sizeof 返回 size_t 类型的值,这是一个无符号整数,但是不是新类型,C 头文件会使用 typedef 机制把 size_t 作为 unsigned int 或者 unsigned long 的别名,具体是哪个,在编译期间编译器根据具体机器确定。

使用 printf 输出 sizeof 的返回值也是个合理的需求,C99 中新增了 %zd 用于显示 size_t 类型,如果不支持,可以使用 %u 或者 %lu

表达式和语句

每个表达式都有值,比如 6 + (c = 3 + 8) 虽然看起来奇怪,但是完全合法。

表达式末尾加上 ; 就是一条语句,所以每个语句都有值。可以有空语句。

声明不是语句,这和 C++ 不同。

C 中有个术语,副作用(side effect),副作用是对数据对象或者文件的修改。如语句 status = 1; 副作用是把变量的值修改了,虽然这是主要目的,但是从 C 的角度来看,主要目的是对表达式求值。给出 1 + 2 ,C 会对其求值为 3 ,给出 status = 1 ,C 会对其求值为 1,求值的副作用是把变量的值修改为 1。

**序列点(sequence point)**是程序执行的点,在该点上,所有的副作用都在进入下一步之前发生。语句中的 ; 标记了一个序列点。一些运算符也有序列点,此外任何一个完整的表达式也是一个序列点。

序列点有助于分析后缀自增何时发生。

对于 y = (4 + x++) + (6 + x++); 这样的表达式,只能确定在 ; 前会自增两次。实际程序这么写很容易出问题。

类型转换

自动转换

表达式里使用混合类型,C 会自动用一套规则自动转换,虽然方便但是危险。

一些转换规则:

  • 有无符号的 charshort 都转换为 int,K&R 的 C,float 会转换为 double (现在的 C 不会)。这些转换称为升级(promotion)

强制转换

(void*)0

循环

while

关于控制条件,C 中 0 为假,不为 0 为真,因此许多程序员会用 while(status) 替换 while(status != 0)

C 对真的概念约束很少,早期就使用 int 来表示真假,C99 新增了 _Bool 类型。

此类型名关键字有点奇怪,因此在 C99 以前,已经有很多程序使用 typedef bool int 占用了这个名字,如果这些程序升级 C99 标准,那么会导致一些错误,为了兼容性考虑,就使用了 _ 前缀,避免造成兼容性上的影响。C99 提供了 stdbool.h 头文件,此头文件中把 bool 作为 _Bool 的别名,且把 truefalse 定义为 10 ,包含此头文件,代码可与 C++ 兼容。

C 语言风格的循环读取一个字符

while (scanf("%d", &num) == 1)
{

}

for 循环

for 的用法。

最基本

for (int i=0; i<5; i++)
    printf("%d\n", i);
for (int i=5; i>0; i--)
    printf("%d\n", i);
for (int i=2; i<50; i = i + 15)
    printf("%d\n", i);
for (char c='a'; c<='z'; c++)
    printf("%c\n", c);
for (int i=5; i*i<125; i++)
    printf("%d\n", i);
for (double i=100.0; i<150.0; i = i*1.1)
    printf("%f\n", i);

第 3 个表达式可以是任意的合法表达式。

for (int x=5; y<125; y = (++x * 5) + 50)
    printf("%d\n", i);

可省略

for (; i<125; )
    printf("%d\n", i);
for (printf("start for"); i<5; i++)
    printf("%d\n", i);

可在循环体内改变循环头

for (int i=0; i<5; i = i + n)
    printf("%d\n", i);

循环体内修改 n。

此外一个运算符 , 使得在循环头可以做更多的事情。关于此表达式

int a = (1,2,3,5); a 的值为 5。

分支跳转

if else switch continue break case default goto

最后更新于