C言語を習いはじめてまもない者です。getcharとisalphaについて教えてください。
 まず、getcharから。この関数は、キーボードから文字を一文字ずつ読み、読み出した文字を返す。といった働きをするそうですが、この関数を用いて、取り込んだ文字をなぜか、int型で宣言した変数に代入しています。(例:int aなどのaに取り込んだ文字を代入している。)なぜ、文字を取り込んでいるのに、intで宣言した変数に代入すのでしょうか?charで宣言した変数に代入しなくていいのですか?

 次に、isalphaについてです。この関数は、変数に代入されている文字が数字か文字かを判断して、文字が入力されていると、0以外の値を返す関数だそうです。しかし、この関数も、変数の宣言がintです。なぜ、charではなくintで宣言するのでしょうか?

このQ&Aに関連する最新のQ&A

C言語 参考書」に関するQ&A: C言語 参考書

書籍 C++」に関するQ&A: C言語の書籍

A 回答 (2件)

式と評価について調べてみてください。



C言語ではchar,shortは評価段階で暗黙にintへの格上げが行われます。
unsigned char unsigned shortはunsignedに、floatはdoubleに。

「EOFのあつかい」という側面が無いわけではありませんが、C言語の「暗黙の方変換」が席にあっての話です。
charがintへ格上げされるからEOFを返すことが可能となっているのです。

C言語FAQ11.3に『古い書き方の 宣言ではdoubleを使ったほうがわかりやすい)"狭い"(char、short int、float)型は、関数引数や戻り値としては避 けたほうが安全であろう。』とあるように古いタイプ(プロトタイプ宣言の無い)のCでは関数インターフェースにcharやshortは使いませんでした。

stdio(getcharが含まれる)やtypes(isalphaが含まれる)はこの時代に定義されたものであり、関数値/引数がint以上の幅を持つことが前提となっています。

C言語FAQ日本語訳のURLを紹介します。

あと、keronpasさんのお使いの参考書にそのあたりの解説が無いのなら別の参考書を見たほうがよいでしょう。
ウチのページでC/プログラミングの書籍を紹介していますので参考にしてください。
http://www.geocities.co.jp/SiliconValley-PaloAlt …

参考URL:http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
    • good
    • 0

EOF を返したり(getchar())、与えたり(isalpha())しなければならないからです。


EOF は通常 -1 で、これを表現するために unsigned char では足りないので int 型が用いられます。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qマドモアゼルの意味

良く、マドモアゼルの名前を目にしたり耳にしたりするのですが、マドモアゼルってどんな意味なんですか?
私の通うアロマの学校の経営母体がやはりマドモアゼルという名前がつくんです。
それですごく気になって・・・。

Aベストアンサー

英語で言うmissと同じ意味です。
フランス語で、姓や姓名の前につけ、未婚の女性に使います。
マドモアゼル・・だけで呼ぶ時は「お嬢さん」という感じです。

Qchar型+char型ってint型? if(char型==int型)?

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょうか。)


if(a[0]==i) /* char型とint型の比較(?) */
の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。
(私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。)
左辺はchar型のように見えて、じつはint型ですか。


#include <stdio.h>
int main(void)
{
char a[4];
int i=77;
printf("sizeof(int)は%d\n", sizeof(int));
printf("sizeof(char)は%d\n", sizeof(char));
printf("sizeof('M')は%d\n", sizeof('M'));
printf("sizeof(a[0])は%d\n", sizeof(a[0]));

a[0]='M';
a[1]=7+6;
a[2]=a[0]+a[1];
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
printf("sizeof(+a[0])=%d\n", sizeof(+a[0]));

if(a[0]==i) /* char型とint型の比較(?) */
puts("a[0]==i");
else
puts("a[0]!=i");

return(0);
}

ちなみにワーニングもエラーもなんにもでません。

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょう...続きを読む

Aベストアンサー

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優先順位の低い演算子を含む式を裸で渡すことはませんが、( ) で囲めばどんな式でも書けるわけです。

後置式は「配列構文によるアドレス参照式」や「関数呼び出し式」、「メンバ参照式」「後置型インクリメント/デクリメント式」です。
なので、
> sizeof(a[0])
> と書いたら、[ ] という演算子は2項演算子だから、a[0]は単項式になっていない
は、わざわざ ( ) で囲まず sizeof a[0] と書いても、正しい単項式なので問題ありません。
(これらの演算子は、全て sizeof より優先順位が上になっています。)

先に ++ も単項式を取る、ということを書きましたが、++ だって
  ++*(p + n)
のような記述が通るのだから、sizeof でも問題がなくて当然です。

また、例えば ++ では「オペランドは左辺値でなければならない」という原則があり、左辺値でない式に ++ を適用するとコンパイルエラーが発生します。
しかし、sizeof に「オペランドはオブジェクトでなければならない」などという原則を聞いたことがありません。
無論コンパイルエラーも起きませんし、期待通りに式の値のサイズが返ります。
「式の値のサイズ」というのはコンパイル時に判明しているものなので、取得できて当然といえば当然ですが、これがCで定められた仕様かどうかというのは残念ながら見つけることはできませんでした。
ただし、質問にあるような sizeof の文法は全て正しく、警告が出ないのは仕様通りだというのは間違いありません。

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優...続きを読む

Qマドモアゼル夫人の曲

こんにちは。
映画で使われている曲を探しています。

テレビでしばしば聞いたことがあるのですが、
曲名を確認するまでには
至りませんでした。

はっきりとした記憶ではないのですが、
マドモアゼル夫人が登場する映画で
使用されていたと思います。
男性がささやくように歌っていました。
「マドモアゼル夫人」で検索したところ、
「mademoiselle chante le blues」
という曲が出てきましたが、
これではありませんでした。

以上です。
宜しくお願いします。

Aベストアンサー

もしかして、
マドモアゼル夫人、ではなくて
「エマニエル夫人」じゃないでしょうか?

だとしたら
http://p.tl/meMi

Qcharで宣言した変数をstringへの代入で

wchar_t cOrg[128]と宣言している変数にstringで宣言しているstrを

cOrg[i] = str[i];

このように代入することはできたのですが、
char cAns[ 128 ];

このように宣言した変数の値をstrの41番目と42番目に
次のように入れようとするとエラーが出ます。

str[41]=cAns[1];
str[42]=cAns[2];

(エラー内容)
\Form1.h(428): error C2664: 'System::String::String(wchar_t,int)' : 1 番目の引数を 'wchar_t [128]' から 'wchar_t' に変換できません。(新しい機能 ; ヘルプを参照)


このような代入はできないのでしょうか?


プログラムの詳細は下のようなものです。



wchar_t cOrg[128],*p;
String^ str;
String^ str2;

int i;
int iVal1,iVal2,iTotal = 0,iHosu;
char cAns[ 128 ];


str = this->textBox1->Text;

for(i=0;i<41;i++)
{
cOrg[i] = str[i];

}

-------(中略)------------------------------------------

iHosu = ~iTotal; // 1の補数
iHosu++; // +1
iHosu = iHosu & 0x00FF;
sprintf( cAns, "%s%02X%c", cOrg, iHosu, 0x22 );
str[41]=cAns[1];
str[42]=cAns[2];

wchar_t cOrg[128]と宣言している変数にstringで宣言しているstrを

cOrg[i] = str[i];

このように代入することはできたのですが、
char cAns[ 128 ];

このように宣言した変数の値をstrの41番目と42番目に
次のように入れようとするとエラーが出ます。

str[41]=cAns[1];
str[42]=cAns[2];

(エラー内容)
\Form1.h(428): error C2664: 'System::String::String(wchar_t,int)' : 1 番目の引数を 'wchar_t [128]' から 'wchar_t' に変換できません。(新しい機能 ; ヘルプを参照)


このような代入はできないの...続きを読む

Aベストアンサー

http://msdn.microsoft.com/ja-jp/library/system.string(v=vs.80).aspx

の解説に書かれてますが、System::String の内容は変更できません。
System::Text::StringBuilder なら

str[41]=cAns[1];

のような操作が可能なので

System::Text::StringBuilder ^str = gcnew System::Text::StringBuilder(this->textBox1->Text);
・・・
str[41]=cAns[1];
str[42]=cAns[2];
this->textBox1->Text = str->ToString();

のようにするといいのではないでしょうか。

Q開発プロセス(プロトタイプ/スパイラル/インクリメンタル)

システム開発プロセスについて整理しています。
整理した結果、以下のような理解をいたしました。
合っていますでしょうか。

・プロトタイプモデル
「要件定義を行い、早期に試作品を作成してユーザの要求と開発側の認識に
ずれがないか確認する」プロセスが含まれているウォータフォールモデルがベースの開発モデル。。

・スパイラルモデル
独立性の高い機能をサブシステムに分解し、それぞれ要件定義、
設計、製造、テストを行いプロトタイプを作成する。
そのプロトタイプを顧客に見せ、フィードバックを得てから
再度プロトタイプを作成してゆく開発モデル。

・インクリメンタルモデル
システム全体の要求定義を行い、機能ごと製造~テストを経て段階リリースする開発モデル。

Aベストアンサー

こんばんは。30代男です。
開発経験者でありながら、今まで気にしてなかったので関連サイトを調べてみました。
誤解があるかもしれませんが…


プロトタイピング
実動するプロトタイプを早期に制作する手法、過程。

プロトタイピング・モデル
要求をあつめ、プロトタイピングを行いユーザーがそれを検証する。

スパイラルモデル(反復型)
トップダウン設計とボトムアップ設計の長所を生かした手法。
設計とプロトタイピングを繰り返していく。

ウォーターフォール・モデル
「要求定義」「設計」「プログラミング」「テスト」「運用」を順に行う。


「プロトタイピング・モデル」「スパイラルモデル」はNo.1の方が指摘されてますので、その通りかと思います。
実際の開発現場での適用方法は私には分かりかねますが・(^^;


「プロトタイピング・モデル」については、開発の流れを示すものではなく文字通り「プロトタイピングする」開発スタイルを指しているのだと思います。
なので「スパイラルモデル」も広義には「プロトタイピング・モデル」になるのでしょうね。


「スパイラルモデル」と「ウォーターフォール・モデル」は開発工程の流れを指しており、「プロトタイピング・モデル」は開発の流れではなく「プロトタイピング」という工程(プロセス)を含んでいるかどうかを指していると理解しました。


質問者様は教育にでも利用するのでしょうかね?


参考になれば幸いです。

こんばんは。30代男です。
開発経験者でありながら、今まで気にしてなかったので関連サイトを調べてみました。
誤解があるかもしれませんが…


プロトタイピング
実動するプロトタイプを早期に制作する手法、過程。

プロトタイピング・モデル
要求をあつめ、プロトタイピングを行いユーザーがそれを検証する。

スパイラルモデル(反復型)
トップダウン設計とボトムアップ設計の長所を生かした手法。
設計とプロトタイピングを繰り返していく。

ウォーターフォール・モデル
「要求定義」「設...続きを読む

Qdoubleの変数にintとintの割り算の結果を代入するとき

以下のようにするとdには0.5ではなく0が代入されます。

int x = 1, y = 2;
double d = x / y;

これを回避するために以下のようにするのが一般的だと習いました。

//1.
double d = (double)(x) / y; // これでdには0.5が代入される

これを以下のようにしてしまうのに問題はあるでしょうか?

//2.
double d = (double)(x) / (double)(y);
//3.
double d = x / (double)(y);

また、1.と2.と3.ではどれがより良いのでしょうか?
単純に好みの問題なのでしょうか?

以上、よろしくお願いいたします。

Aベストアンサー

恐れ入ります。

単純に好みの問題かと思います。
CやC++の規格に準拠したコンパイラであれば、結果的に同じ式として扱ってくれます。
***
ただし、1,2,3ではない別種の方法を良く用いるので参考までに挙げておきます。

int x = 1;
int y = 2;
double dpoX = 0;
double dpoY = 0;
double d = 0;

dpoX = (double)x;
dpoY = (double)y;
d = dpoX / dpoY; /* 計算するときには、精度を揃えておく */

整数を使う場面では整数を使い、倍精度の計算をするときには倍精度で計算するのが良いかと。混ぜると混乱の元です。
(個人的には、ハナからdoubleで取り扱うべきかと思います)

速度的には前述の1,2,3と同様に、計測できるほどの速度低下にはなりません。
(可読性を犠牲にするのは、「除算は遅いから使いたくない」という様な時だけにする方が良いと思います)

ご参考になれば幸いです。

Qプロトタイプ宣言について

C言語で関数を作成しプロトタイプ宣言するときの質問です。
関数実体の引数に構造体のポインタを宣言します。
プロトタイプ宣言には,構造体のポインタを宣言したのと同じ位置にvoid *を宣言します。
関数実体とプロトタイプ宣言は,異なるファイルです。
このように作成した関数は,VC++2008では,コンパイルできるのですが,
なぜ関数実体の宣言とプロトタイプ宣言の型が異なるのにコンパイルできるのでしょうか?

また,この関数を別ファイルの関数から呼び出した場合,正しく引数を理解し,正しく処理されます。
これは,言語仕様として正しい書き方なのでしょうか?
それとも環境依存の書き方なのでしょうか?

ご存知の方がいましたらお答えお待ちしています。

Aベストアンサー

> 言語仕様として正しい書き方なのでしょうか?
殆どの環境が完全に基準に準拠しているわけではないので、
言語仕様や規格云々をこまめに気にしても仕方ないとは
思いますが、気になるなら規格書くらいは一読する事を
お勧めします。

>この関数を別ファイルの関数から呼び出した場合,
>正しく引数を理解し,正しく処理されます
C言語の規格では
「呼び出される関数を表す式が関数原型を
含む型を持つ場合実引数の個数は仮引数の個数と
一致しなければならなず各実引数は対応する仮引数の型の非修飾版を
もつオブジェクトにその値を代入することのできる型を
持たなければならない。」
とされています。

void*であれば如何なる型のポインタ型にも変換でき、
ポインタ型は不完全オブジェクトから派生することができる
非修飾型となる為、関数の仮引数から実引数に渡す事が
可能だからだと思われます。

>それとも環境依存の書き方なのでしょうか?
環境依存に依存すると思います。
しかし、宣言時の関数の型と定義時の関数の型が
異なる為、基本的にはその様な実装は控えるべきでしょう。

そもそも、宣言をvoid*にする意味が全く分かりません。
どうせ、その構造体以外もポインタは処理できないのだから、
構造体のポインタを受け取るべきです。

> 言語仕様として正しい書き方なのでしょうか?
殆どの環境が完全に基準に準拠しているわけではないので、
言語仕様や規格云々をこまめに気にしても仕方ないとは
思いますが、気になるなら規格書くらいは一読する事を
お勧めします。

>この関数を別ファイルの関数から呼び出した場合,
>正しく引数を理解し,正しく処理されます
C言語の規格では
「呼び出される関数を表す式が関数原型を
含む型を持つ場合実引数の個数は仮引数の個数と
一致しなければならなず各実引数は対応する仮引数の型の非修飾版...続きを読む

Qint型変数をchar型変数に格納する方法

int型数値をchar型変数に格納したいのですが、
sprintf()とatoi()を用いてやりましたが、
うまくいきません。
考えたコードを下記します。

int get_y(){

int y=2005;

return y;
}

int main(){

char year;
char str[5];

//intをcharに変換して格納している
sprintf(str,"%d",get_y());

//数値として代入
year=atoi(str);

//yearには2005が格納されていない!
cout<<year<<endl;


char ans; //このchar型変数に数値を代入する。

ans=year;

cout<<ans<<endl;

return 0;

}


お手数をお掛けしますが、
よろしくお願い致します。

Aベストアンサー

私にも2005が6を返すと言う意味が分かりません。

char型は先の説明にある通り、-128~127までしか、値を入れる事は出来ません。
char yearに127を格納すれば、127と出ますが、128と入れれば、ぐるっと一周して-128となってしまいます。
それで言うと、2005を代入すると、グルグルと周って-43と出ます。それならまだ分かるのですが・・・

32ビット環境で、符号付きで考えたとき、
char 1バイト(-128~127)
short 2バイト(-32768 ~ 32767)
int 4バイト(-2147483648 ~ 2147483647)
までしか入れられない。と言う事はお分かりでしょうか?

2005と言う数値をどんなにキャストしようが、char型の変数にその値を格納する事は出来ません。

get_y()が返す値を-128~127の値になるようにするか、yearをcharでは無く、shortやint型に素直に変更する必要があります。

2005をどうしてもcharに格納したいのなら、それは不可能です。

私にも2005が6を返すと言う意味が分かりません。

char型は先の説明にある通り、-128~127までしか、値を入れる事は出来ません。
char yearに127を格納すれば、127と出ますが、128と入れれば、ぐるっと一周して-128となってしまいます。
それで言うと、2005を代入すると、グルグルと周って-43と出ます。それならまだ分かるのですが・・・

32ビット環境で、符号付きで考えたとき、
char 1バイト(-128~127)
short 2バイト(-32768 ~ 32767)
int 4バイト(-2147483648 ~ 2147483647)
までしか入れられ...続きを読む

Qプロトタイプ?

職業上、最近「プロトタイプ」という言葉
をよく耳にします。特に「プロトタイプの
プログラム」ともよく言われますがいまい
ちよくわかりません。
誰か初心者でもわかるように言葉の意味を
教えて下さい。

Aベストアンサー

プロトタイプとは日本語で「試作」という意味です。
一般的にプログラムのプロトタイプは主軸となるロジック以外の機能を削減して工数を激減して作成し、
動作を確認し、仕様通りに作成した場合、実動にどのような影響が出るかを確認するものです。

例えば、このOKWeb(教えてGoo)を作成する場合、
ユーザーがログインして、質問を書いて、別のユーザーが再度ログインし、それに回答を書く。
それを質問したユーザーが確認できる。
まずこの程度の機能をもったものを短い期間で作り上げるわけです。
もちろん、画面は絵などなく、文字情報だけのもので。
それを実際に使ってみて、使い勝手やお客様の要望を網羅できているか等を確認するわけです。

基本的に工数削減のため、本番用のPGはプロトタイプPGを骨組みとして肉付けしていく形を取るケースが多いです。

Qchar型にint型の数値を代入する。

たとえば、
int num;
char box; 

numに何らかの整数値が入っているときに、そのnumの中に入っている値をchar型に文字列として代入したいときはどのようにすればいいのでしょうか?

Aベストアンサー

sprintf()っていう関数がありますよ。書式は

sprintf(char型の配列の先頭ポインタ,フォーマット,変数...)

二番目の引数以降はprintf()の引数と同じです。たとえば

int num;
char box[256];
num=100;
sprintf(box,"%d",num);
printf("%s",box);

→100と出力される


人気Q&Aランキング

おすすめ情報