C语言的基本数据类型:
1、在C语言中,仅仅有四种基本数据类型----整型、浮点型、指针和聚合类型(如数组和结构等),其它类型都是有这四种基本类型某种组合派生而来。
2、整型包括:字符、短整型、整型和长整型(同时区分unsigned和signed)
3、malloc分配一块连续的内存,内存空间首先向内存池要,如果不够再向OS要,OS不能提供则返回NULL,所以有必要对malloc的返回值做是否NULL的判断。
4、calloc也用于分配内存,和malloc主要区别是,calloc能对申请完的内存进行初始化
5、relloc用于修改一个原先已经分配的内存块的大小。使用该函数可以使一块内存扩大或缩小。
6、向free传递一个NULL参数不会产生任何效果。
7、编译一个C程序,第一个步骤就是预编译(prcprocessor)阶段。
8、C预处理在源代码编译之前对其进行一些文本性质的操作。它主要任务包括删除注释、插入被#include指令包含的文件的内容、定义和替换由#define指令定义的符号以及确定代码的部分内容是否应该根据一些条件编译指令进行编译。
9、宏和函数的区别:
-----------------------------------------------------------------------------------------------------------
属性| 宏 函数
-----------------------------------------------------------------------------------------------------------
代码长度 变成 调用同一份代码
执行速度 更快 函数调用/返回,有开销
操作符优先级 别忘记加括号 仅仅在函数调用时求值一次
参数求值 有可能有副作用 参数仅仅求值一次
参数类型 与类型无关,只要合法 与类型有关,参数不同需不同函数
10、函数指针,最常用的两个用途:转换表(jump table)和作为参数传递给另一个函数(常用于回调函数)。
11、简单声明一个函数指针并不意味着它马上就可以使用,和其他指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数
比如:int func(int)
int (*pf)( int ) = &func; //操作符”&“是可选的
12、例子:(函数指针:类型无关的链表查找)(1、应用:回调函数)
/**在一个单链表中查找一个指定值的函数,他的参数是一个指向链表第一个节点的指针,
**一个指向我们需要查找的值的指针和一个函数指针,
**它所指向的函数用于比较存储于链表中的类型的值 */
Node *search_list( Node *node, void const *value, int (*compare)(void const *, void const *))
{
while( node != NULL)
{
if( compare( &node->value, value) == 0)
break;
node = node->link;
}
return node;
}
13、一个整型比较函数实现
int compare_ints(void const *a, void const *b)
{
if( *(int*)a == *(int*)b)
return 0;
else
return 1;
}
这个函数将像下面被使用:
desired_node = search_list( root, &desired_value, compare_ints);
注意强制类型转换:比较函数的参数必须声明为void*以匹配查找函数的原型,然后把它们再强制转换为int*类型,用于比较整型值。
另外,如果你希望在一个字符串链表中进行查找,像下面执行就OK了,
desired_node = search_list(root, "desired_string", strcmp);
碰巧,库函数里有strcmp的实现。
14、转换表就是一个函数指针数组
15、创建一个转换表需要两个步骤:首先,声明并初始化一个函数指针数组,注意:函数原型必须出现在函数指针数组之前,其次,就是替换。
16、例子:(函数指针:类型无关的链表查找)(2、应用:转换表)
计算器的例子:
switch( oper )
{
case ADD: result = add( op1, op2); break;
case SUB: result = sub( op1, op2); break;
case MUL: result = mul( op1, op2); break;
case DIV: result = div( op1, op2); break;
......
}
上面的switch语句如果有很多的话,变得很很冗长,使用下面的方法,更加简洁
double add( double, double);
double sub( double, double);
double mul( double, double);
double div( double, double);
......
double (*oper_func[])(double, double) = {add, sub, mul, div, ......};
现在只需要仅仅调用一个函数就可以把先前的整个switch语句替换掉:
result = oper_func[oper](op1, op2);
oper从数组中选择正确的函数指针,而函数调用操作符将执行这个函数。
///提示及警告:转换表的下标要想办法控制,不然如果越界,问题有时候会变得更糟。