C语言多维数组初始化


by HPC_ZY


由于剧情,需要纯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]);

在这里插入图片描述

  1. 两种方法写法的区别
    (写法)
    使用数组法时,数组大小只能使用常量,不能填入变量,如:
    double mat[Num]; (此为错误)
    但数组法可在定义时,赋初始值,如:
    int mat[5] = {1,2,3,4,5};
    (大小)
    数组法内存在栈中,空间小,能支持的数组尺寸小;
    指针法内存在堆中,空间大,能支持大尺寸数组。
    因此对于尺寸固定的小数组可使用数组法,其他推荐使用指针法

  2. 关于memset()函数
    三个参数分别为(变量指针,初值,字节数);
    对于uint8类型,初值可设为0~255
    其他类型建议仅在初始值为0时使用menset(),如需赋其他值,可使用for循环。
    (具体原因感兴趣可自行学习menset()的原理)

    扫描二维码关注公众号,回复: 11466603 查看本文章
  3. 关于sizeof()
    如果熟悉类型的字节数,可直接写入,如:
    int* mat = (int*)malloc( 10 * sizeof(int) );
    int* mat = (int*)malloc( 10 * 4 );


三、多维数组初始化

特别注意指针法内存分配与赋初值的方式

1、二维

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));
}
// 查看略

在这里插入图片描述

2、三维

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));
}
// 查看略

在这里插入图片描述

  1. 指针法赋初值时,不可直接使用如下格式:
    memset(mat2d2 0, Rows * Cols * sizeof(double));
    memset(mat3d2 0, Rows * Cols * Dims * sizeof(double));
  2. 定义三维数组,建议将Dims放第一维。因为做三维图像处理时,经常需要提取某一帧图像。如一个尺寸为**V(512, 512, 100)**的体数据,提取第10帧图像,则
    MATLAB: frame10 = V(:, :, 10);
    C: double ** frame10 = V[9];

其他

以上仅为使用方案,关于原理不做讲述。想深入研究的选手,可自行百度以下内容:

  1. 数据类型
  2. 数组
  3. 指针
  4. malloc
  5. memset
  6. 堆栈

猜你喜欢

转载自blog.csdn.net/xsz591541060/article/details/90632437