プロが教える店舗&オフィスのセキュリティ対策術

ポインタ勉強中です。
これを関数にしたいのですが
ファイルからaとa2を読み込んで
その値をmainでまた別の関数に入れようと考えています。

#include <stdio.h>
int main(){
int i, j;
unsigned char a[16]= {
0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff};
unsigned char a2[16]= {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f};

unsigned char b[4][4], a3[4][4], c[4][4];//配列格納用

/* インプット */
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
b[i][j]=a[i+(j*4)];
printf(" %02x",b[i][j]);
}
printf("\n");

}
printf("\n");
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
key1_1[i][j] = a2[i+(j*4)];
printf(" %02x",a2[i][j]);
}
printf("\n");

}
printf("\n");

for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
c[i][j] = (b[i][j] ^ a3[i][j]);
}
}


このような感じにしたいです。
int main(){
int i,j;
unsinged char bin1[16]={0};
unsinged char bin2[16]={0};
ファイル読み込み  省略

 kansuu(bin1,bin2,hoge);

for(i=0,i<4;i++){
for(j=0,j<4;j++){
printf("%02x",hoge[i][j]);
}
}

void kansuu(unsigned char a,unsigned char b,unsigned char c){
3つ用意してa,bを入れるとcが返ってくるような

もしくはそのほかいい方法があれば教えていただけるとありがたいです。

質問者からの補足コメント

  • key1_1[i][j] = a2[i+(j*4)];のkey1_1についてa3の間違いでした。

      補足日時:2021/01/28 21:30

A 回答 (3件)

大きさが決まっていて、どうしても配列を使いたいなら、


unsigned char hoge[4][4];
と宣言した上で、kansuu()は次のような宣言になります。
void kansuu(unsigned char *a, unsigned char *b, unsigned char c[4][4]);

多次元配列を関数の引数に取る場合、一番左の元以外は数を指定してあげないといけません。
これでもOKです。
void kansuu(unsigned char *a, unsigned char *b, unsigned char c[][4]);

ちなみに、*aでOKなのは、1次元配列(つまり一番左の元だけ)だからです。

なぜそうじゃなくてはいけないかというと、多次元配列の場合、右の元から順に実際に格納する相対位置を決めているので、これらの相対位置が決まらないと関数内部で直線的なメモリの番地に対応させることができなくなるためです。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
多次元配列だと相対位置等がかかわってくるんですね、勉強になります。
c[][4]の右の元というのは[0][4]の位置を見てるということでしょうか?

大きさが決まっていなくて配列を使わない場合についてはどうしたらいいのでしょうか?

お礼日時:2021/01/28 21:37

2つの配列の排他的論理和を別の配列に格納する関数を作るのであれば、


関数内では全て1次元配列として処理するのが単純で分かりやすいかと。引数に要素数を追加しています。
以下、例です。

void kansuu(unsigned char *in1ptr, unsigned char *in2ptr, unsigned char *outptr, int length)
{
while (length--) {
*outptr++ = *in1ptr++ ^ *in2ptr++;
}
}

void main(void)
{
unsigned char bin1[16] = {
0x00, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff,
};

unsigned char bin2[16] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
};

unsigned char hoge[4][4];

int i, j;

for (i = 0; i < sizeof(bin1); i++) {
printf("%02x", bin1[i]);
}
printf("\n");
for (i = 0; i < sizeof(bin2); i++) {
printf("%02x", bin2[i]);
}
printf("\n");

kansuu(bin1, bin2, &hoge[0][0], sizeof(bin1));

for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
printf("%02x", hoge[i][j]);
}
}
printf("\n");
}
    • good
    • 1
この回答へのお礼

回答ありがとうございます。
このようなやり方もあるんですね。
参考になります。
この方が同じ1次元でやりやすいですね。
今後このようなやり方もとりいれてみます。ありがとうございます。

今回はすいませんが最初に当初の回答いただいたNo1さんをベストアンサーにさせていただきます。

お礼日時:2021/01/29 09:34

「大きさが決まっていなくて配列を使わない場合」ってのは, 具体的にはどんな使い方を想定している?



あと, 処理系によっては「可変長配列」ってのが使えることもある.
    • good
    • 1
この回答へのお礼

回答ありがとうございました。
「大きさが決まっていなくて配列を使わない場合」ってのは, No.1さんの大きさが決まっていて、どうしても配列を使いたいなら、ということにたいして配列を使わない場合はどんなやり方なのかと思いました。
可長変配列VLAも勉強してみます。

お礼日時:2021/01/29 04:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!