作为指针替代的引用,形式上与指针有很大的区别,主要体现在引用只是用作某个变量的别名,并没有为声明的引用名分配内存。在引用声明的同时,必须进行初始化,格式为:数据类型 &引用名 = 某个变量,如下所示:
int iNum = 10;
int &n = iNum; //注意n 不是iNum的地址,而是可以看作为就是iNum(别名么^-^),既然它具有指针的特性,则n = *p = iNum,n就为iNum的指针。
C++提供引用的用法,主要是为了避免直接将指针地址作为参数值传递给函数,从而减低使用指针带来的风险。函数参数使用引用传递,最终编译后,仍然是使用指针来传递的,这样又利用了指针高效的数据传递能力。
#include "iostream.h"
void Add10(int &x) //使用引用作参数,不要以为是取地址!!
{
x+=10;
}
void main()
{
int n = 3;
cout<<"使用引用作参数的用法"<<endl;
Add10(n);
cout<<n<<endl;
}
输出结果:
使用引用作参数的用法
13
Press any key to continue
结论:如果一个函数希望像上面的Add10(n)一样,在参数中直接写入需要处理的输入变量,同时又可具有指针的数据传递功效,那么定义这个函数时,可以在该参数的类型后面加上一个&符号表示变量引用。
1. 结构体和联合体
基本的数据类型可以为各种不同的数据指定相应的内存分配空间,但是对于一些互相关联的数据,如图象文件,在程序源代码中集中定义,可以起到隔离其它数据的作用,清晰表明程序数据的用途。
结构体中的数据在内存中是连续存放的,与数组不同,结构体中的各个成员变量可以是不同的数据类型,而数组则是相同类型的数据集合。定义的一般形式为:
struct 结构体名
{
数据类型 成员变量1;
数据类型 成员变量2;
数据类型 成员变量N;
};
结构体已经定义就可以用来定义具有该结构的变量,一般的使用形式为
struct 结构体名 变量名;
上面定义的结构体变量,仍需使用struct关键字,十分的不方便,可应用C语言提供的类型定义,将结构体类型定义成一个新的数据类型,这样定义该类型的变量时,就可以省去书写struct的麻烦。例如:
typedef struct struc_data_tag
{
char name[8];
char sex;
int year;
}struc_data;
这时定义struc_data类型的变量,就不用在前面加上struct关键字,与普通的类型变量保持一致。如:
Struc_data student1;
那么在C++中,已经允许声明结构体变量,不需要在前面加上struct关键字,而且可在C++的结构体中定义函数,这种结构体相当于变量和函数都是public 的一个类。
在opencv 中定义IplImage的数据类型如下方式:
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* ignored by OpenCV */
int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_
32F
and IPL_DEPTH_
64F
are supported */
char colorModel[4]; /* ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style) */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead */
int width; /* image width in pixels */
int height; /* image height in pixels */
struct _IplROI *roi;/* image ROI. when it is not NULL, this specifies image region to process */
struct _IplImage *maskROI; /* must be NULL in OpenCV */
void *imageId; /* ditto */
struct _IplTileInfo *tileInfo; /* ditto */
int imageSize; /* image data size in bytes
(=image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* pointer to aligned image data */
int widthStep; /* size of aligned image row in bytes */
int BorderMode[4]; /* border completion mode, ignored by OpenCV */
int BorderConst[4]; /* ditto */
char *imageDataOrigin; /* pointer to a very origin of image data
(not necessarily aligned) -
it is needed for correct image deallocation */
}IplImage;
那么定义时用IplImage *image即可,而不是struct IplImage* image;
联合体union又称共用体,共用体的意思就是各种数据类型享用同一块存储空间。也就是说他们的空间类型是其中的一种,而不是每种都代替。定义方式:
union 联合体名
{
数据类型 成员变量1;
数据类型 成员变量2;
数据类型 成员变量N;
};
联合体类型所占用的内存空间,是其最长的成员变过量所占的存储空间,而不是其所有变量占用内存空间的总和。
联合体的用法:联合体一般与结构体结合使用,例如:定义一个数据类型的datatype标志和一个可存放多种类型数据的联合体,程序可以根据datatype的标志,进行相应的数据处理
typedef struct sturct_data_tag{
int datatype;
union{
int iValue;
float fValue;
char* pValue;
}
}process
process process1
if(process1.datatape ==INT)
{
//process
}
if(process1.datatape == FLOAT)
{
//process
}
在opencv 中对CvMat的定义如下:
typedef struct CvMat
{
int type; /* CvMat signature (CV_MAT_MAGIC_VAL), element type and flags */
int step; /* full row length in bytes */
int* refcount; /* underlying data reference counter */
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data; /* data pointers */
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows; /* number of rows */
int cols; /* number of columns */
#endif
} CvMat;