質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • C

    4946questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

プログラムの内容がうまく呑み込めないので、説明をお願いできますか。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 392

sanchu52

score 160

void chop(char *p)を説明して頂いたのですが、今朝そのあとを見たらint len = strlen(p); のpはポインタですよね、それの長さを求めているのはなぜか。
chop(&str[2]);の2は何なのか
printf(" %02X", *p & 0xff);*p & 0xffの計算は何のためにしているのか。
すみません。全体的にわからないということです。あとmain(),dump()も。
説明していただければわかると思うのですが、よろしくおねがいいたします。

コード
#include <stdio.h>
#include <string.h>

void chop(char *p) {
    //for (; *p; p++)で文字列の終端('\0')が見つかるまでポインタを進めます。
    //ループを抜けるとポインタは'\0'を指しているはずです。
    //なので、ポインタを1文字戻します (p--;)。
    //その後、while (*p == '\r' || *p == '\n')で改行が見つかったら
    //クリア('\0'で埋める)する*(p--) = 0;
    //改行がある限り文字列の終端を先頭方向に後退させている。
  for (; *p; p++)
    ;
  p--;

  while (*p == '\r' || *p == '\n')
    *(p--) = 0;
}

void chop2(char *p) {
  int len = strlen(p);    //\0は含まない
  for (int i = 0; i < len; i++) {
    if (p[i] == '\r' || p[i] == '\n') {
      p[i] = 0;
    }
  }
}
void dump(char * p, int len) {
  for (int i = 0; i < len; i++) {
    printf(" %02X", *p & 0xff);
    p++;
  }
  printf("\n");
}
int main(int atgc, char** argv) {
  char str[10];

  strcpy(str, "0\n");
  printf("[%s]\n", str);
  chop(&str[2]);
  printf("[%s]\n", str);
  dump(str, sizeof(str));

  printf("\n");
  strcpy(str, "0\n");
  printf("[%s]\n", str);
  chop2(&str[2]);
  printf("[%s]\n", str);
  dump(str, sizeof(str));

  return 0;
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

strlen

strlenは渡されたポインタから始まる文字列の文字数を返します.
この場合str[2]からの文字数を数えるわけですが,str[2]の中身は'\0',つまり終端文字なのでstrlenは0を返します.

chop(),chop2()

chop()は文字列の後ろから改行文字がなくなるまで終端文字に入れ替えていましたが,chop2()では指定位置から終端記号までに存在する改行文字すべてを終端記号に入れ替えます.なのでstr[2]のポインタを渡した時はfor文の中は実行されずに終了します.ただしstr[1]やstr[0]のポインタを送った場合にはfor文の中が実行され,chop2()の後に続くprintfではchop()の後に続くprintfと同じ出力になります.

str[2]の2

str[2]は文字列の3文字目を表しています(配列は0から始まるのは知っていると思います).strcpyでstrには"0\n\0"が入っているので,3文字目は'\0'です.

dump()

dump()の中身の処理は渡された配列全体の要素を表示するだけです.dump()内の"printf(" %02X", *p & 0xff);"ですが,printfの"%02X"は少なくとも2桁で整数型の変数の中身を16進数で表示せよという意味になっています.しかし今回表示しようとしている変数の型はchar型です.しかしprintfには表示する値の型は整数型と言っているので,printfは渡された変数の型がchar型だろうとお構い無しに整数で表示しようとします.ここで0xffが活きます.0xffは文字の部分だけを表示するための処理に用いている思ってください.試しにこれをなくして実行してみると表示がおかしくなる場合があります(場合によっては何も変わらないと思います).

0xffを正しく表した場合,0x000000ffと書けます.この0xffというのは1から8ビット目まで1でそれ以降は0を表しています.これをビット演算で*pと合わせることで,1から8ビット目までのビットを得ることができ,char型は8bit(1byte)なのでこれで文字の値を得ることができます(ビット演算について知らない場合は調べて見てください,すぐに出てきます).

dump()の引数のsizeof()ですが,なぜlengthではないかというとdump()内で配列全体の要素を表示したいためです.今回の場合だとsizeof(str)は10になる一方,length(str)は1になります(chop()で'\n'は'\0'に入れ替えられているため).

dump()は配列の要素をすべて表示しようとするので,まだ値を入れていない部分も表示します.このため,値を入れていない部分の表示ではデタラメな値が出てきます.

main()

main()は各関数の呼び出しとその結果を表示しているだけのように見えます.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/11 12:31

    BitMaPTさん、tacsheavenさん、丁寧な説明をしていただきありがとうございます。
    この説明を見比べながらこのプラグラムを理解したいと思っています。今夜は仕事なのでねます。
    明日ゆっくり勉強させていただきます。

    キャンセル

0

strlen は引数として与えられたポインタから先にある、「null が出てくるまで」の距離、つまりはnull までの長さを返します。ポインタそのものではなく、ポインタが指し示す先のメモリ領域の長さです。

&str[2] は、まず str[2] で、str が示すポインタから2単位移動した場所の内容です。文字列でいけば(先頭を0として)2個先の文字を意味します。そして & がつくことで、ポインタを指します。結果的にこれは、「str で示される文字列の、(先頭を0としたときの)2文字目を表すポインタ」となります。

C 言語においてはポインタ操作は鬼門にして奥義ですので、しっかりと勉強なさってください。CPU がどうやって動いているのか、というのを合わせて調べていくと、理解しやすいかも知れません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4946questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。