• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:教えて下さい。C言語の文法の意味!!)

C言語の文法の意味とは?

このQ&Aのポイント
  • C言語の文法について詳しく教えてください。
  • ポインタや計算方法に関する疑問を解説してください。
  • どのような結果が得られるのか知りたいです。

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

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.5

「こんなコードをコメントなしで書いてきたら問答無用で却下する」というのは私も#4と同じです。 が、それはそれとして解読し得る範囲で。 回答1: 普通はこういう定数値(一般にマジックナンバーと呼ばれます)はその意味がわかるようにdefineしておくのが常識です。 なんらかのデータフォーマットにそった計算方法だろうとは思いますが、この数字だけでは何をやっているのかを読み取ることはできません。 結果は、もちろんbuff[5*16+5+(16*21+6)]のアドレスが得られますよ。 それが何を意味するかは、上記の理由によりさっぱりわかりませんが。 回答2: tp-4のtpというのは質問1で求めたアドレスですね。 その4個前、tpはcharのポインタですから4バイト分前のアドレスを求め、そのアドレスをunsigned intのポインタと見做した上で参照外しを行う、つまりtpの直前4バイト分をunsigned int型と解釈した数値がstrbsに出力されます。 tp-65のほうはさっぱりわかりませんね。65の手がかりになるものが全くないので。

r32yokoyok
質問者

お礼

回答ありがとうございます。仕様みたいなので確認したいと思います。ありがとうございました。

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

その他の回答 (4)

回答No.4

分からん。 ちなみに、こんなプログラムを部下や上司が出してきても認めん。 汚すぎる。。。。

r32yokoyok
質問者

お礼

回答になっていないようなぁ??? そこは目をつぶって上げて下さいm(_)m

全文を見る
すると、全ての回答が全文表示されます。
noname#140045
noname#140045
回答No.3

質問1:1つ1つの数字についての意味はわかりませんが、このように書くメリットは'5*16+5+(16*21+6)'に意味があるからです。 これをあらかじめ計算結果の数字を書いてしまうと、何がなんだかわからないものになってしまいます。 そして、一番重要なことは、この計算はコンパイル時に結果が求められるため、実行時の処理速度には影響しないと言うことです。 つまり、電卓などであらかじめ計算した答えを書くのと、なんら変わりがないと言うことです。 もちろん、可読性は全然違います。 質問2:char *tp だとよくわかりませんが、たとえば型が long *tp だとしたら tp+1 とした場合には計算時にはtpの値に4が加算されます。 つまり、tp[1]と考えればいいでしょう。 つまり、+1だからと言って必ず1が加算される訳ではなく、その変数の型によって違って来るのです。 これも4や65に、何らかの意味があるのでしょう。

r32yokoyok
質問者

お礼

そうなんですよね!!意味があると思うのですが、C言語の特有の書き方だと勘違いしてしまいました。作成した方に連絡を取って仕様を聞いてみようと考えています。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • neko1963
  • ベストアンサー率49% (127/258)
回答No.2

質問1については、5*16+5+(16*21+6)=427 で buff先頭から427バイト目(?)アドレスをポインタに入れているようですが、 buffの中にどのような内容がどのようなレイアウトで入っているのかわからなければ "5*16+5+(16*21+6)"の意味はわかりません。 プログラムを書いた人に尋ねなければ、他の人はわからないのではないでしょうか。 質問2 tp-4 はポインタtpの4バイト前(?)でしょうから、tpの4バイト前(?)からunsigned intにキャストして10進数8桁として strbに格納する? いずれにしても、 buffの中にどのような内容がどのようなレイアウトで入っているのかわからなければ、どうしようもありません。 プログラムを作った方にお尋ねになった方が良いと思います。

r32yokoyok
質問者

お礼

そうですね!!作成した方に聞いてみたほうが早そうですね!!ありがとうございます!!

全文を見る
すると、全ての回答が全文表示されます。
  • mnabe
  • ベストアンサー率33% (427/1283)
回答No.1

そりゃぁ載っていないでしょ。 可読性の問題だけでしょうからね。 tp は、バッファ領域を作成しているのだと思うのですが、その領域を計算式で求めているだけですからね。どんなプログラムで利用しているのか解りませんが、 16バイトが21個合ってそれに6バイト足した物と5バイトが16個ある物に5バイト足した物を合算しているって意味なんでしょうね。 実際に、そのプログラムを動かしてみるのが一番の様な気がしますけど、それが出来ない理由でもなるのですか? tpは、ポインタを参照しているアドレスを保持しているので、そこからのアドレス値での減算を行って値を持ってくるって事をしているのでしょう。

r32yokoyok
質問者

お礼

参考資料にこれしかなくて・・・・C言語をメイクやコンパイルする環境がないので何かまでは分からないので解読してました。規則性があるのかと思ったのですが、ただのバイトの加算減算処理なのですね。ありがとうございます。

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

関連するQ&A

  • C言語のコンパイル時に表示される以下のエラーの意味を教えて下さい。

    C言語のコンパイル時に表示される以下のエラーの意味を教えて下さい。 また、できれば解決方法も教えて下さい。 「パラメータ '__buffer' は signed char * 型として定義されているので int は渡せない」 このエラーの該当箇所は、以下のsprintf文です。 for(i = 0 ;i < sign; ++i){  sprintf(HEXDATA[i],"%02X",rbuf[i]); ← このステップです } なお、HEXDATA、rbuf、i、signは、  char HEXDATA[256];  char rbuf[256];  int i,sign; と定義しています。 rbufには入力ファイルから読み込んだテキストデータ「0123456」が入っており、 これを1文字ずつ16進数に変換して、順にHEXDATA[1]、HEXDATA[2]、HEXDATA[3]~~~ に格納していきたいのですが、どうしたら良いのでしょうか。

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

  • C言語でのコンパイルエラー

    初心者です。 非常に基本的な質問かもしれませんが、 ご回答いただけたらうれしいです。 void test1(unsigned char* data) { } void test2(unsigned char** data) { } int main(void) { unsigned char data1[6]; unsigned char data2[6][6]; test1(data1); test2(data2); } としてtest1はうまくいくのに、 test2はコンパイルエラーになります。 どっちもポインタになると思うのですが…。 また、unsigned char data2[6][6]を 他の関数の引数とする場合は どうすればよろしいのでしょうか? 宜しくお願いいたします。

  • C言語のビットフィールドについて

    はじめまして,今C言語を勉強中なのですが, ビットフィールドの宣言について質問があります。 勉強に使用しているテキストでは, ビットフィールドの宣言にはunsigned int型を使用すると書かれています(下記例参照)。 ここで質問は,unsigned charなどの型は推奨されない理由があるのか,ということです。 実際にunsigned char型で実行してもプログラムは動きますし,そちらのほうが語長も短くて済むのでいいような気がします。 テキストの書き方だと,他の型について言及していなかったので,なにか理由かあるのか,それとも特に問題ないのか,疑問に思っています。 わかる方いましたら,回答いただけると嬉しいです。 (ex) struct{ unsigned int bit0:1; unsigned int bit1:1; : unsigned int bit7:1; }bits;

  • C言語について教えてください。

    数日前に「http://okwave.jp/qa4903738.html」で質問させてもらった者です。 前回、寝起きでボケてるうちに回答を締め切ってしまって、 回答してくださった方との対話ができていませんでした。 すみません。 今回は前回の指摘された部分を含めて回答を戴きたく投稿させてもらいます。 質問内容はほぼ変わりありません。 CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 あと、fgetsは使わないようにしたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ----------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou o) { printf("%d\n%s\n",o.nenrei,o.namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); return 1; } fread(buff1, 1, NUM, fp); // ここでファイルの内容が全てbuffに入る。 // printf("%s\n",buff1); // buff1にファイルの内容が書き込まれているか確認する。 while((buff2[n] = buff1[n]) != NULL) // buff2[0]からbuff1の中が終わるまで一文字ずつコピーしていく。 { if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { p.nenrei = atoi(buff2); // char型からshort型への変換し、p.iAgeに入れていく。 } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ----------------------------------------------- 前回指摘されたwhileの条件式ですが、 まだchar型とポインタを比べてることになっているので正しくないんですよね? 正直、どうすればいいかわかりません。 あと、今のままでは名前3の後が改行ではないので表示されることないですよね・・・。 どうすれば表示されるようになるでしょうか。 これも前回言われましたが while内の1つ目のif文の所で、カンマを処理したので次に取り込むbuff2への書き込み位置の変更というのもわかりません。 カンマが来た時点でbuff2[n]のnは2になっているんですよね? ということはbuff2[3]からまた読み込めたらいいということですよね? 厚かましくも立て続けに質問してしまって申し訳ありませんが回答を戴けたらありがたく思います。 宜しくお願いします。

  • C++で日付判定を行いたい!!

    C++で日付判定を行いたい!! C++でデータを1バイトづつ呼んで(For文で回す)日付かどうかを判断したいのですが、VBのようなIsDateみたいな関数がないので、同じように扱える関数がC++であったら教えてください。 対応する関数が無い場合は参考になるようなサイトでもやり方でも結構ですので、教えてください。 例> tp=&buf[4*16+(16*3)]; //ポインタ for( ixs = 0;ixs<50;ixs++){  //日付判定チェックがしたい  sprintf(aaa,"%08d",*((unsigned int*)(tp+ixs))); } 宜しくお願いします。

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

  • C言語についてアドバイスをください。

    CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou *o) { printf("%d\n%s\n",o->nenrei,o->namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 short i = 0; int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); } fread(buff, 1, NUM, fp); while(buff1[n] != NULL) { buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。 if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { i = (short)atoi(buff2); // char型からshort型への変換 p.nenrei = i; } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ------------------------------------------------------- 今のままだと 『11 11,名前1 11 11,名前1 15,名前2』 という表示になってしまいます。 while 内で既に読み込んだ部分を読み込ませないよう(表示させないよう)にできたら良いと思うんですが、そういったやり方はあるのでしょうか? むしろやり方を変えたほうが良いでしょうか・・・。 まだC言語を学び始めて日が浅いので、色々間違っている部分もあると思いますが、 そういったことを含めてアドバイスをいただけたらと思います。 よろしくお願いします。

  • C言語の文法(変数宣言)について

    C言語の文法の質問をさせていただきます。 int hoge; などと宣言しますが、このintというのは型指定子というものでしょうか。 int *piyo; という宣言のintも型指定子でしょうか。 この場合、* はなんと呼ばれるのでしょうか。(アスタリスクという記号です、という回答は期待していません。(^_^;)) ポインタ宣言子、でいいのでしょうか。これは「演算子」ではないんですよね? char c[10]; という宣言の[ ]やその中に入っている10はなんと呼ばれるのでしょうか。 いま、手元に「新ANSI C言語辞典」という本があるのですが、説明を読んでもよくわかりません。

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }