- 締切済み
配列の長さについて
現在課題で書いているプログラムに以下のような関数があるのですが、 unsigned char key[32]; int w[60]; int data[NB]; int nk; int nr; int data2[32]; int Cipher(int *); int invCipher(int *); void encryptEBC(int *); void decryptEBC(int *); main(){ unsigned char keys[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; unsigned char iv[]={0xcb,0x70,0x05,0x9e,0x27,0x2f,0x4e,0xd2, 0xd0,0xbe,0x0b,0x06,0xbf,0x16,0xec,0x5a}; unsigned char init2[]={'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0',0x0a}; //unsigned char init2[]={'h','e','l','l','o'}; int isize = sizeof(init2)/sizeof(init2[0]); int dsize2 = sizeof(data2)/sizeof(data2[0]); printf("%d,%d\n",isize,dsize2); FILE *fp; char *fname = "test.txt"; unsigned char init[16]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); memcpy(key,keys,16); nk = 4; nr = nk + 6; KeyExpansion(key); memcpy(data,init,16); memcpy(data2,init2,isize); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data,16); datadump("KEY: ",key,16); Cipher(data); datadump("Cipher: ",data,16); invCipher(data); datadump("invCipher: ",data,16); printf("\n"); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data2,dsize2); encryptEBC(data2); printf("%d\n",dsize2); datadump("EBCCipher: ",data2,dsize2); decryptEBC(data2); datadump("invCipher: ",data2,dsize2); printf("\n"); return 0; } void encryptEBC(int data[]){ int dsize = sizeof(data)/sizeof(data[0]); int tmp[16]; int i,j,k; printf("%d\n",dsize); KeyExpansion(key); for (i = 0; i < dsize; i += 16) { for (j = 0; j < 16; j++){ tmp[j] = data[i + j]; } Cipher(tmp); for(k=0;k<16;k++){ data[i+k] = tmp[k]; } } } 関数encryptEBC内のdsizeの値がこの場合だとmain内の配列data2の長さ32になってほしいのですが、1になってしまいます。 非常に見ずらいプログラムで申し訳ないのですが、どなたか1になってしまう理由、またどうすれば正しくdata2の長さを求められるか教えていただけないでしょうか?
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- nissii202
- ベストアンサー率33% (1/3)
補足すると sizeof() は関数ではなく演算子で 実行時ではなくコンパイル時に評価されるため 動的に長さは取れないのです。
- Tacosan
- ベストアンサー率23% (3656/15482)
本題じゃないけど.... 「main内の配列data2の長さ32になってほしい」って書いてあるけど, data2 って配列は main の中にはないよねぇ. あと, 3回使ってる memcpy のうち最初の 2回で定数をベタに書いてある理由がよくわからない. sizeof とかを使ってあげようと思ってもいいんじゃないかな. ついでに最後の memcpy で使っている isize も (値は正しいけど) 意味は間違ってる気がする.
- hitomura
- ベストアンサー率48% (325/664)
関数の仮引数として int f(int[] a) と書いてもそれは int f(int *a) と解釈されます。つまり関数内で sizeof(a) としたら、たとえ a が関数の呼び出し元では配列であってもポインタのサイズを返します。 どうしても配列のサイズを関数内で知りたいならば、別の引数でサイズを渡しましょう。 それが嫌なら、 ・データに絶対出ない値があるなら文字列のようにデータの最後の値を取り決めておく ・この関数は与えられたポインタに規定の長さがある領域を指す必要があると明言して利用者にそれを厳守させる ・渡す配列が int の場合のみ限定の手段として 1 個めのデータはデータ長を表すと明言して利用者にそういうデータを作らせる という手もあります。まあたぶん今回の場合は上記の 1 番目はダメで 2, 3 番目は利用者が不便なので素直にサイズを別変数で渡すべきだと思いますが。