设为首页 加入收藏

TOP

C语言知识补遗
2014-11-23 21:42:09 来源: 作者: 【 】 浏览:14
Tags:语言 知识 补遗

函数前使用extern没有意义;extern用在变量前表示变量是一个外部链接符号。(函数天然是一个外部链接符号)

――与此相关的,指定函数的调用风格(__cdecl, __stdcall, __fastcall)等,或者生成动态连接库时(__declspec(dllimport)、__declspec(dllexport)),或者指定编译语言类型时(C, C++)时,都只需要在 声明体(.h文件) 中说明,不需要在实现体(.c文件)中说明。

同时,static对于函数和变量的意义也不同。

非可移植的内存分配技巧:(要求平台的malloc库实现时采用连续分配,用途:概要访问,隐式存储)

struct name {

int namelen;

char namestr[1];

};

#include

#include

struct name *makename( char *newname )

{

struct name *ret = malloc(sizeof(struct name)-1 + strlen(newname) + 1);

if (ret != NULL) {

ret->namelen = strlen(newname);

strcpy(ret->namestr, newname);

}

return ret;

}

C99引入了许多C++中已有的特性:结构体越来越像 类 了――可以创建无名的临时 结构体变量

结构体的sizeof值是内存占用范围,“空洞”也计算在内

如何计算field在struct中的字节偏移量?

非可移植方案:#define offsetof(struct, f) (size_t) ( (char*) (struct*)0->f - (char*) (struct*)0 )

不要使用内建的==或!= 来比较结构体变量――编译器对齐操作可能会导致结构体的稀疏,出现空洞

在需要指针型的地方,如何传入一个常量?

如intf(int *)函数,怎样传入一个常量? ――在C99中,可以使用“复合字面量”:f( (int[]){5} ); 类似Java??

函数名本质上也是一个地址,类似数组名; 函数指针本质上也是一个可以参与 赋值、算术 的变量。 () 是唯一可以用于函数指针的后缀运算符。

不同的是,函数名、函数指针的地址实际上是代码区或者说ROM的地址,而数据变量名、数据指针的地址实际上是数据区RAM的地址,二者不能通用。例如,空的函数指针为void (*)(),空的数据变量指针为void *;

NULL没有想象中的省力――在函数参数传入时,仍然需要使用类型转换。

一般来说,NULL仅仅是一个提示:这里是一个指针0,没有其他意义。所以,在不需要指针的地方(如ASCII空字符:)不要用它。

使用规则:

1、在需要空指针常量时,用0或NULL都是等价的;

2、在函数调用传入0时,根据原型在0或NULL前添加强制转换;

为什么需要NULL?因为NULL(表示空指针)在某些平台上实现为0,而在另一些平台上用特殊值来实现――为什么C标准不把它统一定义为0?因为在某些平台上用特殊值来触发自动的硬件陷阱,可以捕捉到空指针非法访问的错误,统一用0实现空指针是一种不幸的倒退。

数组并非C语言一级元素,下标也并非一级运算符,而是定义在指针算术运算基础上――因此,a[i] 等价于 *( (a) + (i) ),也等价于 i[a]。

通过定义不同类型(主要是维数)的指针p,关联数组a后,可以对p实现++或--不同粒度的重载。

一本C语言的习题汇编:

C Programming FAQs, Steve Summit, 人民邮电2008

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇有符号数和无符号数间的比较 下一篇 c语言的f函数小结

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: