由于剧情,需要纯C(不用三方库)实现图像算法。但作为一名MATLAB老用户,根本不知“指针”“内存”为何物。开始自信满满,结果连初始化一个二维全零矩阵都不会(尴尬),顾从零学起,在此总结。
今后会持续更新MATLAB函数的C实现,欢迎交流,共同学习。
.
注:C语言博大精深,实现方法众多。由于本文主题是M2C,所以在方法和格式上会尽量贴近MATLAB。还望各大C佬请勿吐槽。
.
MATLAB | C | 字节数 |
---|---|---|
char | char | 1 |
uint8 | unsigned char | 1 |
uint16 | unsigned short int | 2 |
int32 | int | 4 |
single | float | 4 |
double | double | 8 |
利用sizeof(type)函数可返回类型的字节数
/*关于数据类型*/
printf(" MATLAB - C - Byte\n");
printf("( char = char ) %d\n", sizeof(char));
printf("( uint8 = unsigned char ) %d\n", sizeof(unsigned char));
printf("( uint16 = unsigned short int) %d\n", sizeof(unsigned short int));
printf("( int32 = int) %d\n", sizeof(int));
printf("( single = float ) %d\n", sizeof(float));
printf("( double = double ) %d\n", sizeof(double));
MATLAB
Num = 10;
mat1d1 = zeros(1,Num); % 默认为double
mat1d2 = zeros(1,Num,'uint8');
C
// 内存分配
int Num = 10;
double mat1d1[10]; // 数组法
unsigned char *mat1d2 = (unsigned char*)malloc(Num * sizeof(unsigned char)); // 指针法
// 值初始化
memset(mat1d1, 0, Num * sizeof(double));
memset(mat1d2, 0, Num * sizeof(unsigned char));
// 查看
printf("mat1d1:");
for (int k = 0; k < Num; k++)
printf("%.0f ", mat1d1[k]);
printf("\nmat1d2:");
for (int k = 0; k < Num; k++)
printf("%d ", mat1d2[k]);
两种方法写法的区别
(写法)
使用数组法时,数组大小只能使用常量,不能填入变量,如:
double mat[Num]; (此为错误)
但数组法可在定义时,赋初始值,如:
int mat[5] = {1,2,3,4,5};
(大小)
数组法内存在栈中,空间小,能支持的数组尺寸小;
指针法内存在堆中,空间大,能支持大尺寸数组。
因此对于尺寸固定的小数组可使用数组法,其他推荐使用指针法
关于memset()函数
三个参数分别为(变量指针,初值,字节数);
对于uint8类型,初值可设为0~255;
其他类型建议仅在初始值为0时使用menset(),如需赋其他值,可使用for循环。
(具体原因感兴趣可自行学习menset()的原理)
关于sizeof()
如果熟悉类型的字节数,可直接写入,如:
int* mat = (int*)malloc( 10 * sizeof(int) );
int* mat = (int*)malloc( 10 * 4 );
特别注意指针法内存分配与赋初值的方式
MATLAB
Rows = 2, Cols = 3;
mat2d1 = zeros(Rows,Cols,'int32');
mat2d2 = zeros(Rows,Cols);
C
int Rows = 2, Cols = 3;
// 数组法
int mat2d1[2][3];
memset(mat2d1, 0, Rows * Cols * sizeof(int));
// 指针法
double **mat2d2 = NULL;
mat2d2 = (double**)malloc(Rows * sizeof(double*));
for (int r = 0; r < Rows; r++){
mat2d2[r] = (double*)malloc(Cols * sizeof(double));
memset(mat2d2[r], 0, Cols * sizeof(double));
}
// 查看略
MATLAB
Rows = 2, Cols = 2, Dims = 3;
mat2d1 = zeros(Rows,Cols,Dims,'int32');
mat2d2 = zeros(Rows,Cols,Dims);
C
int Rows = 2, Cols = 2, Dims = 3;
// 数组法
int mat3d1[3][2][2];
memset(mat3d1, 0, Rows * Cols * Dims * sizeof(int));
// 指针法
double ***mat3d2 = NULL;
mat3d2 = (double***)malloc(Dims * sizeof(double**));
for (int d = 0; d < Dims; d++)
mat3d2[d] = (double**)malloc(Rows * sizeof(double*));
for (int d = 0; d < Dims; d++)
for (int r = 0; r < Rows; r++){
mat3d2[d][r] = (double*)malloc(Cols * sizeof(double));
memset(mat3d2[d][r], 0, Cols * sizeof(double));
}
// 查看略
以上仅为使用方案,关于原理不做讲述。想深入研究的选手,可自行百度以下内容: