C/C++陷阱与缺陷

来源:互联网 发布:培训seo教程 编辑:程序博客网 时间:2024/06/13 18:45

//++a与a++
++a,在a存储的值上增加1并向使用它的表达式“返回”新的a值;
a++,向使用它的表达式“返回”a的值,再对a加1。
例如,下列程序:
a=5;b=5;
printf("%d\n",++a);
printf("%d\n",b++);
输出结果:
6
5
而a和b的结果都为6

//如何得到一个类型转换符
一旦知道了如何申明一个给定类型的变量,那么该类型的类型转换符就很容易得到:只需要把申明中的变量名和申明末尾的分号去掉,再将剩余的部分用一个括号整个“封装”起来即可。

//运算符优先级
数组下标,函数调用操作符,各结构成员选择操作符。自左于右结合。
单目运算操作符。自右于左结合。
算目运算符之算数运算符、移位运算符、关系运算符、逻辑运算符。自左于右结合。
三目条件运算符。自右于左结合。
赋值运算符。自右于左结合。
,运算符。自左于右结合。

//边界计算与不对称边界
用第一入界点和第一出界点表示一个数值范围。这里的下界是入界点,即包括在取值范围之中;而上界是出界点,即不包括在取值范围之中。这种不对称也许从数学上而言并不优美,但它对于程序设计的简化效果确是令人惊奇的:
1、取值范围的大小就是上界与下界之差。
2、如果取值范围为空,那么上界等于下界。
3、即使取值范围为空,上界也用于不可能小于下界。

//static指针
被修饰的变量或者函数不可以被本模块以外的其他任何模块使用。

//溢出的判断原理

//extern "C"的惯用法

(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:
extern "C"
{
#include "cExample.h"
}
而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。
C++引用C函数例子工程中包含的三个文件的源代码如下:
/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/* c语言实现文件:cExample.c */
#include "cExample.h"
int add( int x, int y )
{
return x + y;
}
// c++实现文件,调用add:cppFile.cpp
extern "C" 
{
#include "cExample.h"
}
int main(int argc, char* argv[])
{
add(2,3); 
return 0;
}
如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。
(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接 引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。
C引用C++函数例子工程中包含的三个文件的源代码如下:
//C++头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif
//C++实现文件 cppExample.cpp
#include "cppExample.h"
int add( int x, int y )
{
return x + y;
}
/* C实现文件 cFile.c
/* 这样会编译出错:#include "cExample.h" */
extern int add( int x, int y );
int main( int argc, char* argv[] )
{
add( 2, 3 ); 
return 0;
}

//extern对于变量与函数使用的区别
如何使用extern以及static
extern 和static的使用方法,应该属于C语言的基础知识了。可是,在实际工作中,还是经常会在代码里看到关于这两个限定符使用的问题,总结一下,大致有两类:其一,对于模块中的变量或者函数,不了解到底加不加static 或者 extern修饰符;其二,在加限定符的时候,不知道正确的使用方法。因此,有必要旧话重提,说明一下。 
简单的说,记住两句话即可, 
1 Static表示:被修饰的变量或者函数不可以被本模块以外的其他任何模块使用;而extern恰恰相反,表示同意其被被本模块以外的其他模块使用;
2 当变量或者程序没有被static或者extern 修饰的时候,变量或者函数可以被其他模块使用。 
这么说可能还是比较空洞,看程序吧。 
假定有两个模块 A 和B, 模块B希望使用在模块A中定义的一些变量和函数,我们应该怎么做呢? 
1 A不“表态”,B了解A的实现细节,自行取用. 
/*----------------------------------------------
 Moudle_A.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/ 
//declaration of the variable and function 
int index; 
void UserFunction(void); 
//implementation of the function
void UserFunction(void)
{
    .....
    //use the index
    
    iRecord = index;
    .... 

/*----------------------------------------------
 Moudle_B.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/
extern int index;
extern void UserFunction(void); 
//operate on the 'index' and 'UserFunction()'
...
/*----------------------------------------------
 Moudle_B.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/
extern int index;
extern void UserFunction(void); 
//operate on the 'index' and 'UserFunction()'
... 
这里,index 和UserFunction 在模块A中声明的时候,A没有使用任何限定符,所以编译器理解,不做限制。所以,当模块B希望使用的时候,是允许的。但是,这不是一个很好的风格,有点不问自取的意思,不推荐。 
2 A主动公开,B正常使用; 
/*----------------------------------------------
 Moudle_A.h
 This module contains the prototype information
 ----------------------------------------------*/ 
//declaration of the variable and function 
extern int index; 
extern void UserFunction(void); 
/*----------------------------------------------
 Moudle_A.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/
#include "Moudle_A.c" 
//initialize the variable
... 
//implementation of the function
void UserFunction(void)
{
    .....
    //use the index
    
    iRecord = index;
    .... 

/*----------------------------------------------
 Moudle_B.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/
#include "Moudle_A.h" 
//operate on the 'index' and 'UserFunction()'
... 
这个例子中,模块A 提供了一个头文件,公开了index 和UserFunction的信息,明确的提供给其他模块。当模块B包含了模块A的头文件的时候,就可以使用index 和UserFunction了。模块A和B互相配合,B对A中变量和函数的使用,合理合法,推荐。 
3 A主动保护,B无法使用; 
/*----------------------------------------------
 Moudle_A.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/ 
//declaration of the variable and function 
static int index; 
static void UserFunction(void); 
//initialize the variable
... 
//implementation of the function
void UserFunction(void)
{
    .....
    //use the index
    
    iRecord = index;
    .... 

/*----------------------------------------------
 Moudle_B.c
 This module contains the variable and function
 that user defined
 ----------------------------------------------*/
#include "Moudle_A.h" 
extern int index; 
extern void UserFunction(void); 
//operate on the 'index' and 'UserFunction()'
... 
这个例子中,模块A 用static 限定了index 和UserFunction的作用范围,明确表示了不希望他们被别的模块引用。此时,即使模块B了解index 和UserFunction在模块A中的具体信息,试图用extern声明,并且在自己的代码中引用的时候,也不会成功,编译出错。


//如何书写安全可靠的宏表达式

//代码移植性问题

原创粉丝点击