こんにちは
K&Rを読んでいるのですが、p.95のgetop(char s[])について質問します。
(1)関数本体の4行めにある
s[1] = '\0';
は、何のためにあるのでしょうか?
(2)9行めと12行めで、
while( isdigit(s[++i] = c = getch()) )
とあるのですが、なぜs[i++]とせずにs[++i]として、cを格納するs[i]を、s[0]ではなくてs[1]から始めているのでしょうか?
/* getop: 次の演算子あるいは数値の被演算数をとってくる */
int getop(char s[])
{
int i, c;
while( (s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0'; /* ← (1) */
if( !isdigit(c) && c != '.')
return c; /* 数ではない */
i = 0;
if(isdigit(c)) /* 整数部を集める */
while( isdigit(s[++i] = c = getch()) ) /* ← (2) */
;
if(c == '.') /* 小数部を集める */
while( isdigit(s[++i] = c = getch()) ) /* ← (2) */
;
s[i] = '\0';
if(c != EOF)
ungetch(c);
return NUMBER;
}
No.6ベストアンサー
- 回答日時:
以下のような場合はdefaultでsも使ってるので'\0'は必要でしょう
while((type = getop(s)) != EOF) {
}
switch (type) {
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '\n':
printf("\t%.8g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
演算子として'+'、'-'、'*'、'/'以外のものを指定した時に出力されるエラーメッセージをきちんと出すためにs[1] = '\0'としているということが分かりました。
おかげさまですっきりしました。
どうも有難うございました!
No.5
- 回答日時:
No.4です。
再コメントします。今、手元にK&Rがないので、getop()の呼び出し元の処理を
私の方で確認できないのですが、getop()の戻り値がNUMBER以外の場合に
getopに指定した配列の内容を参照しないようになっているのであれば、
(1)はそのサンプルコーディングを実行する上で必須のコードではないと
考えてよいと思います。
その場合、(1)が必要か否かは、作者がgetop()の関数仕様を
どのように考えているか次第ということになると思います。
(戻り値がNUMBER以外の時に、文字列sは不定値になるか否か。
または、戻り値がNUMBER以外の時に文字列sの参照を許可するか否か。)
なお、仕様で扱いが決まっていない場合でも、配列sを中途半端な
状態で放置せず、文字列として終端をきちんと処置しておくのは、
行儀がよく安全なコーディングであると言えると思います。
>配列sを中途半端な
>状態で放置せず、文字列として終端をきちんと処置しておくのは、
>行儀がよく安全なコーディングであると言えると思います。
とても参考になりました。
どうも有難うございました!
No.4
- 回答日時:
(1)の件について、
例えば「+」という演算子の入力があった場合、
getop()は、配列sに"+"という文字列を設定して
返却することが意図されていると思います。
s[1] = '\0';
は、"+"のような1文字の文字列を形成するために必要な
文字終端設定処理です。
もし
s[1] = '\0';
がない場合、s[1]には以前に使用したゴミデータが入ったままで、
正しく"+"という1文字の文字列にならない可能性があるので、
(1)は必要です。
この回答への補足
if( !isdigit(c) && c != '.')
return c; /* 数ではない */
の部分は、文字列sを返しているのではなく、文字cを返しています。
文字列sを返しているのであれば仰るとおりなのですが、ここでは文字cを返しているので、仰るようにはならないように思います。
No.1
- 回答日時:
(1) 文字列の末端を示すため。
(2) while( (s[0] = c = getch()) == ' ' || c == '\t')
で入力された文字を書きつぶさないよう。
この回答への補足
仰ぎ見るepisteme先生からさっそくご回答をいただきまして、ありがとうございます。
おそれながら、(1)の
while( (s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0'; /* ← (1) */
は、文字(数字か演算子)に先立って入力される不要な空白文字を読み飛ばすために行われている処理なので、s[1] = '\0'は不要なのではないのでしょうか?
このプログラムは、逆ポーランド記法で計算する簡単な計算機で、
入力: 1 2 +
出力: 3
のように動作するものです。
そう考えると、(2)の疑問が出てきました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCL言語で文字列検索方法を教え...
-
バイナリファイル中の日本語文...
-
%dなどの違い
-
16進数を2文字ずつ配列に格納し...
-
[C++]WCHARの1文字目しか表示で...
-
C言語の課題で困っています;
-
C#でstringをポインタとして渡す
-
nullと""、\\0とEOFの違いにつ...
-
文字コードによる表記
-
c#で他のアプリの文字入力フォ...
-
VB6.0でのバイナリデータの扱い...
-
プログラムによく出てくるst...
-
数字の入った配列をファイルへ...
-
Shift_JIS(16進)を文字に変換す...
-
C++で入力した文字列から数字を...
-
c言語のstrncpyについて
-
文字を反転させる。
-
アルファベットの出て来た回数
-
セグメントエラー
-
mallocについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C#でstringをポインタとして渡す
-
プログラムによく出てくるst...
-
C++で入力した文字列から数字を...
-
nullと""、\\0とEOFの違いにつ...
-
c#で他のアプリの文字入力フォ...
-
TCL言語で文字列検索方法を教え...
-
16進数を2文字ずつ配列に格納し...
-
シリアル通信で0x00を送信した...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
WSH(VBS)でJSONの文字列を読み...
-
VB6.0でのバイナリデータの扱い...
-
C++で文字列の右端から特定の文...
-
数字の入った配列をファイルへ...
-
%dなどの違い
-
構造体→文字列→構造体 をする方法
-
char型配列の最大要素数
-
VBA-DLLの引数受け渡しについて
-
[C++]WCHARの1文字目しか表示で...
-
Shift_JIS(16進)を文字に変換す...
-
CSVファイルの「”」について
おすすめ情報