《C专家编程》读书笔记(二)

By:LShang

Blog:http://www.cnblogs.com/LShang

提示一

如果遇见了这样一条语句 malloc(strlen(str));,几乎可以断定它是错误的,而 malloc(strlen(str)+1);才是正确的。这是因为其他的字符串处理库函数几乎都包含了一个额外空间,用于容纳字符串结尾的‘\0’字符。所以,人们很容易忽略 strlen 这个特殊情况。

提示二

一个 ‘L’ 的 NUL 用于结束一个 ASCⅡ 字符串,ASCⅡ字符串中的零的位模式被称为 ‘NUL’

两个 ‘L’ 的 NULL 用于表示什么也不指向(空指针),哪里也不指向的特殊指针值是 ‘NULL’

C 语言多做之过

由于存在 fall through,switch 语句会带来麻烦

default 可以放到语句中的任意位置,在所有 case 语句均不匹配时执行 default 后边的语句(不会因为 default 语句在 case 语句之前而优先执行)

int main()

{
switch(2)
{
case1:
printf("Case 1!");
break;
default:
printf("Default!");
break;
case2:
printf("Case 2!");
break;
}
return0;
}
C:\Turboc2>tcc test
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440762

C:\Turboc2>test
Case 2! // 并未因为 default 语句写在 case 2 语句之前而优先执行 default 语句

switch 的左花括号之后可以定义一些变量,从而进行一些局部存储的分配(这些变量是无法被初始化的,因为 switch 语句将会从 case 语句开始执行)

int main()
{
switch(2)
{
int a;
case1:
a = 1;
printf("a = %d!",a);
break;
default:
printf("Default!");
break;
case2:
a = 2;
printf("a = %d!",a);
break;
}
return0;
}
C:\Turboc2>tcc test.c
Turbo C  Version 2.0  Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440758

C:\Turboc2>test
a = 2! // 变量 a 定义成功,并成功对其赋值和使用
int main()
{
switch(3)
{
int a = 3;
case1:
a = 1;
printf("a = %d!",a);
break;
default:
printf("a = %d!",a);
break;
case2:
a = 2;
printf("a = %d!",a);
break;
}
return0;
}
C:\Turboc2>tcc test
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440730

C:\Turboc2>test
a = 1334! // 对变量 a 的初始化并未完成

当需要一个临时变量时,如果有可能的话,尽量避免使用局部变量。编译器可以自由的忽略它,它可以通过函数调用来分配所有局部块需要的内存空间。另一种用法是声明一些完全局部于当前块的变量。

int main()
{
int a = 1;
int b = 2;
printf("a = %d,b = %d\n",a,b);
if(a<b)
{
int temp = a; /* 定义一个完全局限于当前块的变量 */
a = b;
b = temp;
}
printf("a = %d,b = %d\n",a,b);
return0;
}
C:\Turboc2>tcc test
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 441172

C:\Turboc2>test
a = 1,b = 2
a = 2,b = 1
int main()
{
int a = 0;
for(; 3>a; ++a)
{
int b[3] = {0}; /* 定义一个完全局限于当前块的变量 */
b[a] = a;
printf("b[%d] = %d\n",a,b[a]);
}
return0;
}
C:\Turboc2>tcc test.c
Turbo C  Version 2.0  Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 439884

C:\Turboc2>test
b[0] = 0
b[1] = 1
b[2] = 2

switch 内部的任何语句都可以加上标签,并在执行时跳转到那里,这样就有可能破坏程序流的结构化

int main()
{
switch(1)
{
do_goto:
case2:
printf("2\n");
case3:
printf("3");
default:
break;
case1:
printf("1\n");
goto do_goto;
}
return0;
}

C:\Turboc2>tcc test.c
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440668

C:\Turboc2>test
1
2
3

const 关键字并不表示真正的常量

#define TWO 2 /* 用宏来定义常量 */
int main()
{
constint one = 1;
switch(1)
{
case one:
printf("1");
break;
case TWO:
printf("2");
default:
break;
}
return0;
}

C:\Turboc2>tcc test
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Error test.c 7: Constant expression required in function main
Warning test.c 16: 'one' is assigned a value which is never used in function mai
n
*** 1 errors in Compile ***

Available memory 442438

fall through:如果 case 语句后面不加 break,就依次执行下去,以满足某些特殊情况的需求。
break:跳出离自身最近的那层循环或 switch 语句。

相邻的字符串常量将被自动合并为一个字符串

旧风格

int main()
{
printf("Hello \
World");
return0;
}

新风格

int main()
{
printf("Hello "
"World");
return0;
}

这种自动合并意味着字符串数组在初始化时,如果不小心漏掉一个逗号,编译器将不会发出错误信息,而是悄无声息的将两个字符串合并在一起。。。

int main()
{
char *str[] =
{
"Hello",
"LShang",
"By"/* 没写逗号 */
""/* 没写逗号 */
"LShang", /* 多了一个逗号 */
};
printf("%s",str[2]);
return0;
}

C:\Turboc2>tcc test.c
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440216

C:\Turboc2>test
By LShang

最后一个字符串末尾的逗号不管存在与否都没有什么意义,也无法在其他由逗号分隔的列表中使用

int main()
{
int
a,
b,; /* 单行多变量声明,末尾多写一个逗号 */
return0;
}

C:\Turboc2>tcc test
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Error test.c 5: Declaration syntax error in function main
*** 1 errors in Compile ***

Available memory 443554

可以通过 static 来声明静态变量,表示该变量的值在各个调用之间一直保持延续性

void fun()
{
static int i = 0;
printf("i = %d\n",i);
++i;
}

int main()
{
fun();
fun();
fun();
return0;
}

C:\Turboc2>tcc test.c
Turbo C Version 2.0 Copyright (c) 1987, 1988 Borland International
test.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland International

Available memory 440234

C:\Turboc2>test
i = 0
i = 1
i = 2

太多的缺省可见性

定义 C 函数时,在缺省情况下函数的名字是全局可见的。

function apple(){ /* 在任何地方均可见 */ }

extern function apple() { /* 在任何地方均可见 */ }static function apple() { /* 在这个文件之外不可见 */ }

C 语言误做之过

C 语言的符号重载

C 语言中类似的符号具有多种不同意义

sizeof 并不是一个函数而是一个操作符

当 sizeof 的操作数是歌类型名时,两边必须加上括号,但操作数如果是变量则不必加括号

apple = sizeof(int) * p;

表示 apple 是 p 个 int 值占用的大小

apple = ( sizeof(int) )*p;

表达式整体解析式是从左到右的,所以 sizeof 和 * 优先级一样时,先解析左边,也就是 sizeof(int) ,如果再解析 * 为取指针的值,那表达式就不合法了。

C 语言的运算符优先级

C 语言中有些运算符的优先级是不正确的(但却很难得以改正,因为如果修改了运算符优先级,那么大量现有的代码就会出现问题)

在表达式中如果有布尔运算、算术运算、位操作等混合运算,应该在适当的地方加上括号,使之清楚明了。

结合性:在几个操作符具有相同的优先级时由结合性来决定先执行哪一个。

结合性只用于表达式中出现两个以上相同优先级的操作符的情况,用来消除歧义。

所有优先级相同的操作符,他们的结合性也相同。

 

转载于:https://www.cnblogs.com/LShang/archive/2011/12/11/2283671.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值