小邵的精文

记得当前刚开始学 C/C++ 语言的时候,教科书说 C/C++ 是相对于机器语言的一种高级语言,那么什么是高级语言,也就是高级语言与机器语言本质上有什么区别?对于这个问题,大家可能都听过类似下面的解释:

<pre>

机器语言是面向机器的,高级语言是面向活人的,所以高级语言理容易阅读,容易理解

</pre>

 

那么大家有没有想过为什么高级语言容易阅读?这背后有什么东西在发挥作用?

 

除了模块化的思想以外,最重要的是高级语言中引入的 “类型”!

 

在机器语言中,没有类型,我们在机程序时,一块内存所代表的意义只有程序员的大脑中,如果不了解代码背后的知识,不太容易知道这块内存的意义;

在高级语言中,有了类型,我们通过代码就可以知道一块内存的意义,如:

<pre>

int i;

i 占用了 4 个字节的内存,类型 int 说明我们可以对这块内存进行整数的算术运算操作;

</pre>

<pre>

int *p;

p 也占用了 4 个字节的内存,类型为 int *,说明它是一个指向 int 类型的内存地址,可以进行地址运算操作

</pre>

<pre>

struct l2cap_conn_tag { ... }l2cap_conn;

l2cap_conn 占用了 n 个字节内存,类型为 structl2cap_conn_tag,其类型说明了这块内存代表了一个蓝牙l2cap 连接对象,我们可以对这块内存进行l2cap 相关的操作(如连接,发收数据,断开等)

</pre>

 

可见,通过类型,我们可以明确地知道对一块内存应该使用哪些操作。

 

使用明确的类型,我们可以写出可读性好的代码,另一个方面,也能够让编译器帮你检查出更多的问题,如:

 

<pre>

类型不安全:

 

BTHANDLE hMutex;

BTHANDLE hEvent;

 

BTHANDLE OS_CreateMutex(void);

BTHANDLE OS_CreateEvent(void);

 

hEvent = OS_CreateMutex(); // 本来是要创建 mutex,可传的 handle 却是 event 的,由于类型都是BTHANDLE,所以编译器不会报告这个错误

hMutex = OS_CreateEvent(); // 同上

 

明确了类型,类型安全:

 

typedef struct tagMutex *BTMUTEX;

typedef struct tagEvent *BTEVENT;

 

BTMUTEX hMutex;

BTEVENT hEvent;

 

BTHANDLE OS_CreateMutex(void);

BTHANDLE OS_CreateEvent(void);

 

hEvent = OS_CreateMutex(); // 这时编译就会报告类型不匹配,可以让我们及早地发现代码中的问题

 

</pre>

 

<pre>

类型不安全:

 

float v = 0.1f;

 

printf("%d\n", v); // 类型不对,应该是 %f,printf 就是类型不安全的,但多数编译器不会报错(gcc 可以检查出这个问题,但只是 gcc 的一个扩展,不是所有编译器都支持的)

 

C++ 的 iostream 就是类型安全的:

 

std::cout << v << std::endl;

 

class foo { ... };

 

std::cout << foo <<std::endl; // 会报错,除非重载一个新的且接受foo 作为参数的 << 操作符。

 

</pre>

 

<pre>

类型不安全:

 

#define FLAG1  1

#define FLAG2  2

#define FLAG3  3

 

BTHRESULT func(int flag);

 

声明的一个函数接口,参数只接受FLAG1、FLAG2 和 FALG3,但以下会代码会编译通过,编译器不会发出警告:

 

func(100); // 这不是我们设计接口时所期望的,虽然可以在 func 内通过断言或者参数判断来处理,但这会将问题的发现时间推后,增加修改成本

 

明确了类型,类型安全:

typedef enum

{

   FLAG1 = 1,

   FLAG2 = 2,

   FLAG3 = 3

} flag_t;

 

BTHRESULT func(flag_t flag);

 

func(100); // 多数编译器会报告类型不符的错误或警告

func(FLAG1); // OK

</pre>

 

下面这个之前发贴说过一些,见:

[[http://10.10.109.234:3000/boards/8/topics/275]]

 

<pre>

类型不安全:

 

typedef int BOOL;

#define TRUE 1

#define FALSE 0

 

// 创建一个窗口,通过参数来指定窗口有没有最大化,最小化按钮,能不能由用户改变大小

HWND CreateWindow(BOOL IsHaveMaxButton,BOOL IsHaveMinButton, BOOL IsResizable);

 

// 这个接口就不太好,可以看一个使用这个接口的代码:

HWND wnd1 = CreateWindow(TRUE, TRUE,TRUE);

HWND wnd2 = CreateWindow(FALSE, TRUE,FALSE);

HWND wnd3 = CreateWindow(FALSE, FALSE,FALSE);

 

// 如果不看(或者不了解) CreateWindow 的声明,或者没有接口文档,上面的代码我们完全不知道在创建什么样的窗口

 

明确了类型,类型安全:

 

typedef enum { HAVE_MAX_BUTTON,NO_MAX_BUTTON } MaxButtonFlag;

typedef enum { HAVE_MIN_BUTTON,NO_MAX_BUTTON } MinButtonFlag;

typedef enum { RESIZABLE, FIXED }ResizeFlag;

 

HWND CreateWindow(MaxButtonFlag maxf,MinButtonFlag minf, ResizeFlag rf);

 

这样调用方代码就比较容易阅读:

 

HWND wnd1 =CreateWindow(HAVE_MAX_BUTTON, HAVE_MIN_BUTTON, RESIZABLE);

HWND wnd2 = CreateWindow(NO_MAX_BUTTON,HAVE_MIN_BUTOTN, FIXED);

HWND wnd3 = CreateWindow(NO_MAX_BUTTON,NO_MIN_BUTTON, FIXED);

 

</pre>

 

如果明确了类型,我们可以在编译期及早地发现错误,要不然只能到运行期才能发现问题,众所周知,问题发现的越晚,修改调查的成本就越高。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值