天天看點

C語言多元數組初始化一、常用資料類型對照二、一維數組初始化三、多元數組初始化其他

(M2C系列)C語言多元數組初始化

  • 一、常用資料類型對照
  • 二、一維數組初始化
  • 三、多元數組初始化
    • 1、二維
    • 2、三維
  • 其他

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));
           
C語言多元數組初始化一、常用資料類型對照二、一維數組初始化三、多元數組初始化其他

二、一維數組初始化

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]);
           
C語言多元數組初始化一、常用資料類型對照二、一維數組初始化三、多元數組初始化其他
  1. 兩種方法寫法的差別

    (寫法)

    使用數組法時,數組大小隻能使用常量,不能填入變量,如:

    double mat[Num]; (此為錯誤)

    但數組法可在定義時,賦初始值,如:

    int mat[5] = {1,2,3,4,5};

    (大小)

    數組法記憶體在棧中,空間小,能支援的數組尺寸小;

    指針法記憶體在堆中,空間大,能支援大尺寸數組。

    是以對于尺寸固定的小數組可使用數組法,其他推薦使用指針法

  2. 關于memset()函數

    三個參數分别為(變量指針,初值,位元組數);

    對于uint8類型,初值可設為0~255;

    其他類型建議僅在初始值為0時使用menset(),如需賦其他值,可使用for循環。

    (具體原因感興趣可自行學習menset()的原理)

  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));
}
// 檢視略
           
C語言多元數組初始化一、常用資料類型對照二、一維數組初始化三、多元數組初始化其他

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));
}
// 檢視略
           
C語言多元數組初始化一、常用資料類型對照二、一維數組初始化三、多元數組初始化其他
  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. 堆棧