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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

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

Q&A

解決済

2回答

2524閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2017/11/11 00:25

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; }

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

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 01:50

BitMaPT

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/11 03:31

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

0

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

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

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

投稿2017/11/11 01:20

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問