• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:FatFsのプログラム(ポインタのキャスト?))

FatFsのプログラム(ポインタのキャスト?)

このQ&Aのポイント
  • FatFsのプログラムにおけるポインタのキャストについて
  • ポインタのキャストを使用することの有用性について
  • FatFsに詳しい方からの教えをお願いします

質問者が選んだベストアンサー

  • ベストアンサー
noname#137556
noname#137556
回答No.1

例えば, バイナリファイル(FatFs だからもっと低レベルなところだと思う)のヘッダなんかを読む時, 一旦,まとめて BYTE の配列に読み込んでおいて, その中のデータを WORD 型に解釈しなおすために, そういうのを使うことがあります。 BYTE buf[32]; WORD type, len; fread(buf, 1, 32, fp); type = LD_WORD(buf); len = LD_WORD(buf + 2); 構造体を使うと詰め物が入ったりするし, データを1つ1つ読むのも面倒だったりするので。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 助けてください ポインタと配列

    #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 0}; int i, *ptr; ptr = &a[0]; while (*ptr!= 0){ if(*ptr!=0) *ptr=0; } for (i = 0; i < 5; i++) printf("a[%d]=%2d &a[%d]=%p\n",i,a[i],i,ptr); // 配列aの値とアドレスを表示せよ putchar('\n'); ptr = &a[0]; for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n",*ptr,ptr); ; } // ポインタptr を使用して、修正後の配列aの値とアドレスを表示せよ printf("\n"); return (0); } /* 処理結果 a[0]= 0 &a[0]=0013FF3C a[1]= 2 &a[1]=0013FF3C a[2]= 3 &a[2]=0013FF3C a[3]= 4 &a[3]=0013FF3C a[4]= 0 &a[4]=0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C 続行するには何かキーを押してください . . .*/ 一次元配列a[]の一番目の要素以外を0にするプログラムを作成せよ。 ただし、最後の要素は0とする。 上記の問題文とこの結果は合致しているでしょうか?

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • 書き込みデータのポインタのキャスト変換

    Ç言語初心者です。 あるプログラムソースの一部で、以下のようにfwrite()で書き込みデータのポインタarrayをキャスト変換しています。    FILE *fp; int array[3]; int i; for( i=0; i<3; i++){ array[i] = i; } fp = fopen("sample.tbl","wb"); fwrite( (char *)array, sizeof(array), 1, fp); // (char *)を付ける理由が分からない fclose(fp); (char *)array を array に変更しても結果は変わらないと思いますが、何に影響があるのでしょうか。

  • 関数ポインタの利点

    こんにちは。 C言語初心者ですが今勉強中です。 その中でポインタについては理解できたのですが、 関数ポインタの利点、使うべき所などが理解できません。 ポインタの基本は理解しています。 値渡し、アドレス渡しも理解しています。 関数ポインタを使うと何がいい、またはどんなとき使わなければならないのか 教本を読んでいてもさっぱりわかりません。 サンプルプログラムを打っても何のために使ってるのかわからないです。 どなたか教えていただけませんでしょうか? よろしくお願いします。

  • すいません 下の修正版です。

    #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 0}; int i, *ptr; ptr = &a[0]; while (*ptr!= 0){ if(*ptr!=0) *ptr=0; } for (i = 0; i < 5; i++) printf("a[%d]=%2d &a[%d]=%p\n",i,a[i],i,ptr); // 配列aの値とアドレスを表示せよ putchar('\n'); ptr = &a[0]; for (i = 0; i < 5; i++){ printf("ptr値 =%d ptrアドレス =%p \n",*ptr,ptr); *ptr=a[0]; } // ポインタptr を使用して、修正後の配列aの値とアドレスを表示せよ printf("\n"); return (0); } /* 処理結果 a[0]= 0 &a[0]=0013FF3C a[1]= 2 &a[1]=0013FF3C a[2]= 3 &a[2]=0013FF3C a[3]= 4 &a[3]=0013FF3C a[4]= 0 &a[4]=0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C ptr値 =0 ptrアドレス =0013FF3C 続行するには何かキーを押してください . . .*/ 一次元配列a[]の一番目の要素以外を0にするプログラムを作成せよ。 ただし、最後の要素は0とする。 上記の問題文とこの結果は合致しているでしょうか?

  • ビットマップ画像を読み込むプログラムがうまく行きません。困ってます…。

    こんにちは。大学4年のyu-tinと申します。 現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。 1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、  その画像の1つ1つの画素の輝度値を表示させる 2)読み込んだビットマップ画像を出力させる しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。 a)0行0列~1行383列までの画素値がおかしい。  (0,0,0,0,1,1,1,0,2,2,2,0,3,3,3,0,…,254,0,255,255,255,0 となっている) b)出力した画像の最上部2行程度に、細くて黒い線が表示される。  (読み込んだ画像と全く同じ画像を出力させたい) c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。  (ペイントでは開ける) その問題のプログラムは、以下の通りです。 しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。なので、このプログラム自体、私自身が完璧に理解できていない状況です。 私は、プログラミングに関しては初心者に近いので、丁寧に教えて頂けると大変助かります。 研究が先に進まず、大変困っています…。みなさま、本当に、本当によろしくお願い致します。 //ビットマップ画像に関するプログラム。 //画像の表示と輝度値の表示を行う。 #include<stdio.h> #include<windows.h> #include<stdlib.h> #define X_SIZE 640  //画像の横幅(ピクセル数) #define Y_SIZE 480  //画像の縦幅(ピクセル数) #define Z_SIZE 1    //1つの画素に含まれる色の数 void *malloc(size_t size); void main(void) {  int i, j, k;   //ループ用変数 i…縦の画素用, j…横の画素用, k…色数用  int x=0;    //画像の横幅(ピクセル数)*/  int y=0;     //画像の縦幅(ピクセル数)  FILE *fp; /***********元画像データのメモリ確保*********/  BYTE ***mae;  mae=(BYTE ***)malloc(sizeof(BYTE **)*Y_SIZE);  for(i = 0; i < Y_SIZE; i++){   mae[i]=(BYTE **)malloc(sizeof(BYTE *)*X_SIZE);  }  for(i = 0; i < Y_SIZE; i++){   for(j = 0; j < X_SIZE; j++){    mae[i][j]=(BYTE *)malloc(sizeof(BYTE)*Z_SIZE);   }  } /*******画像の読み込み・輝度値の表示*******/  fp=fopen("sample1.bmp","rb");   //画像”sample1”を開く  BITMAPFILEHEADER bmfh;  BITMAPINFOHEADER bmih;  fread(&bmfh,sizeof(bmfh),1,fp);  fread(&bmih,sizeof(bmih),1,fp);  x=bmih.biWidth;  //インフォヘッダに含まれる画像の幅情報をxに代入  y=bmih.biHeight;  //インフォヘッダに含まれる画像の高さ情報をyに代入  for(i = 0; i < y ;i++){   for(j = 0; j < x; j++){    fread(&mae[i][j][0],sizeof(BYTE),1,fp);    if(i<640 && j<480)printf("%d, %d, %d\n",i, j, mae[i][j][0]);   //輝度値を表示   }  }  fclose(fp); /**************画像の表示*************/  //画像”sample1”を”sample2”という名前で出力する  fp = fopen("sample2.bmp" ,"wb");  //ヘッダの書き込み  fwrite(&bmfh,sizeof(bmfh),1,fp);  fwrite(&bmih,sizeof(bmih),1,fp);  for(i = 0; i < bmih.biHeight; i++){   for(j = 0; j < bmih.biWidth; j++){    fwrite(&mae[i][j][0],sizeof(BYTE),1,fp);   }  }  fclose(fp);  //ファイルをクローズ }

  • 構造体へのポインタの動的確保について

    構造体へのポインタを動的確保しようとmalloc関数を使用すると segmentation faultが起きます。 typedef struct cell{ char *word; int count; struct cell *next; }node_t; という構造体で node_t *ptr=(node_t*)malloc(sizeof(node_t)*num); という風に動的確保しようとするとsegmentation faultが起きました。 gdbを使って調べると Starting program: /home/programII/week05/a.out file1 file2 Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b4ce36 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 というメッセージが返ってきます。 これはライブラリとのリンクが正しく行われていないということでしょうか? しかし、ポインタの動的確保以外でmalloc関数を使用すると 正常に動作するのでライブラリ自体が無いわけではないようです。 ptr[2]といった風にポインタを参照したいのですが上手くいきません。 よろしくお願いします。

  • C言語によるメモリ読み書き

    大学の授業でC言語を勉強しています。 下記のようなサンプルを頂いたのですがいまいち理解できません。 このサンプルは正しいのでしょうか。 Q) cpy_ptr_32はポインタ宣言で、"MEMORY_BASE"の"0x08000000"を入力していますが、その後for文中に"i"が入力されています。 これはデータが『0x08000000』、アドレスが『i』と認識して良いのでしょうか? 上記の場合、"MEMORY_BASE"はアドレスなのに、なぜデータとして扱っているのかが理解できません。 経験が浅いため、サンプルが正しいかも判断がつきません。 宜しくお願いします。 ================================================================ #define MEMORY_BASE 0x08000000 //MEMORYのベースアドレス int main (){ unsigned int* cpy_ptr_32 ; unsigned int read_data_32 ; unsigned int i ; while(1) { // Memory TEST cpy_ptr_32 = MEMORY_BASE ; for(i = 0 ; i < 0x2000000 ; i++){ *cpy_ptr_32 = i ; read_data_32 = *cpy_ptr_32 ; if (read_data_32 != i) { printf ("No Good !!! 32 bit access !!! error_address = %x \n" , cpy_ptr_32); WriteRead(LED ,0,0x0); return(0); } cpy_ptr_32++ ; WriteRead(LED ,0,0x1); } ================================================================

  • プログラムの合成願い

    あらかじめ行列の数がわかっているN行*M列のエクセルデータをCSV形式にし、 読み込むプログラムを作成しました。 そのプログラムを下に示します #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 23 #define M 6 /* データの区切り文字*/ #define SEP_DATA',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン*/ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し*/ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換*/ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す*/ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す*/ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ*/ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保*/ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(double[M]) * N); //malloc(sizeof(*csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化*/ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み*/ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力*/ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } また、行列の数を計算するプログラムを作成しました。(プログラムは別途URLを書き込みます) http://www.kent-web.com/pubc/book/test/uploader/uploader.cgi?mode=downld&no=3797 これら二つのプログラムを合わせかたがわかりません。 プログラムで示していただきたいです。お願いします。 環境はC++です。