• ベストアンサー

標準関数の中身について

最近C言語を学びはじめた初心者です。 標準関数にprintfやsinなどいろいろありますがこれらの中身はどうなっているのですか? 例えばprintfを作った人はif文やfor文など関数でないものを駆使して作っていったということなんですか?しかしif文やfor文だけではディスプレイに表示させたり ということはできないですよね? 単なる数値計算というだけならfor文とかを使ってできそうですが、ディスプレイに表示させたりファイルに書き込んだり、とかいう作業はコンピューター内部でどのようにして実行されているのでしょうか?またそういう関数を自分で作るにはどういう知識が必要なんでしょうか? ちょっと馬鹿っぽい質問かもしれませんがよろしくお願いします。

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

  • ベストアンサー
  • hogeta
  • ベストアンサー率14% (4/28)
回答No.5

標準関数自体は、よく使われるであろう機能や、使いやすくした機能を提供するものです。 例えば、sin関数を必要になるたびに作ってたら大変でしょう。また、画面表示をputcで 全部やるのはもっと大変ですよね。 次にディスプレイなどのデバイス操作に関して説明します。まず、OSがあるからパソコンを 利用することができることはわかると思います。このことから推測できるように、デバイス 操作というものは、すべてOSのお仕事なわけです。なので、デバイス操作は、すべてOSお願 いしているわけです。 わかりやすいように例を挙げます。まず、putchar('a')を実行するとします。 これも標準関数の一つです。putcharは、呼び出されると、OSに対して「'a'という文字を 一文字、標準出力に表示して下さい」とお願いします。printf関数にしても同じで、内部で いろんな処理をしたあと、OSにこの文字を表示してくださいとお願いするわけです。 概ねこんな感じでデバイス操作は行なわれます。 で、このデバイス操作、すなわちOSにお願いするということがifやforでは記述できない ものなわけです。この「OSにお願いする」には、「システムコール」というものを用います。 システムコールは、プログラマにとって関数のようにして使うことができます。例えば、 putcharを実行すると、最終的にはwriteシステムコールが呼び出されます。OSは システムコールによって呼び出されると、引数に従って処理を行なって元のプログラムに制御 が戻るわけです。 じゃあなぜOSを経由しないとデバイス操作ができないの?という疑問が残ります。昔の MS-DOSなんかだと、自分で直接制御できたわけですから。これは「保護」というのが一番の 理由です。MS-DOSのようにプロセスが1つしか実行できないOSなら気をつけてプログラムを 書けばいいだけですが、いろいろなプロセスが実行できる今のOSではいろいろな問題が出てき ます。ですから、OSがすべて代行することでうまくいくというわけですね。 と、かなり長くなってしまいましたが、これでいかがでしょう。

jimihenn
質問者

お礼

詳しいお答えありがとうございます。 なんとなくわかりました。確かになんでOSなんかあるのだろうと思ったりしてましたがそういう理由だったのですね。勉強になりました。

その他の回答 (4)

noname#11476
noname#11476
回答No.4

具体的な実装は処理系(←要はコンピュータの種類ですね。DOS/V,Macなどのハードの違い、OSの違いなど)によって異なってきますが、大まかな概念は次のような物です。 下層から順番に書くと、 1. 特定のメモリ上のデータを表示するハードウェアがある。 2. 一番低位のBIOSというC又はアセンブラでかかれたプログラムがそのハードを制御していて、表示用のFunction Call(要するに関数)をもっています。  具体的な仕事はICなどのポートを叩いたりします。 3.OSはBIOSに文字表示などを指示するための低位の関数を持っています。 4.Cのライブラリ関数の低位関数があり、これらの関数ではOSの低位関数を呼び出すようになっています。 5.printfなどは更にCの低位のライブラリ関数を組み合わせてつくられています。 自分で作る場合は、最低OSの関数に関する知識があれば書けるでしょう。 組み込み機器用のコンピュータのプログラムなどでは、極端な場合では自分で直接ハードを制御する関数群を書いて、ライブラリを作る場合もあります。

jimihenn
質問者

お礼

詳しいお答えありがとうございます。 なんとなくわかりました。 やはりハードとOSレベルの知識がいりそうですね。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

標準関数のソースを見たいということであれば、VC++ならインストールオプションでインストールすることが出来ます。 これをインストールすると、標準関数の中もデバッグできるようになります。 ソースの内容なんですが、あくまでもVC++が実装している内容であって、他のコンパイラが同じ作りになっているとは限らないところに注意をして下さい。 確かに他の方々がいっているように、処理系依存のところはよっぽどのことがない限り、すぐに役に立つとは思えませんが、アルゴリズムの勉強にはなるんでは?と私は思います。

jimihenn
質問者

お礼

ありがとうございます。 もう少し腕を上げてから勉強することにします。

  • Lara-Port
  • ベストアンサー率36% (12/33)
回答No.2

細かい話をすると、プログラミング言語が生まれてきた歴史を話さなくてはいけなくなるので、それはやめます。  C言語は、もともと、UNIX-OSを簡単に開発できるようにするために作成されたもので、UNIX上のアセンブラ言語から開発されたのが始まりです。(UnixはWindowsでいえば、DOS窓のようなものです。)  この時点で、文字をモニタに表示したりする関数などの初歩的なものは、用意されています。この時点のC言語を使って、もっと簡単に使える関数が作られ、ライブラリ化されていって、新しいC言語群となっていきます。これを繰り返し行われて、今のような標準関数たちになっています。そして、いろいろなOSで使用できるような形に修正されていっています。  C言語が持っている関数を一切使わずにC言語でモニタに文字表示するのはできません。また、コンピュータ内部の動きを理解するには、PCのハードウエア分野を深く理解する必要がありますし、プログラミングというソフトウエア面からも見ようとすると、アセンブラ言語の表面的な知識でなく、少々深い知識が必要になってきます。  そういうことを理解するための本が、最近は少し大きい一般書店でも多く置いてありますから、興味があれば、いかがでしょうか?  Cの歴史を参考URLに入れておきます。興味があれば、見てください。  わかりにくい説明だったかな?

参考URL:
http://www.bohyoh.com/CandCPP/C/history.html
jimihenn
質問者

お礼

ありがとうございます。 プロラムの歴史ですか。前途多難ですががんばります。 URLも参考になりました。

  • dtm
  • ベストアンサー率37% (23/62)
回答No.1

No.291691(4つ前)の質問もそうですけど、厳しいかもしれませんが、初心者の気にするようなものではないと思います。少なくとも関数リファレンスを見ずにプログラムを組めるようになった後でなければ全く意味がありませんし、理解できません。 >またそういう関数を自分で作るにはどういう知識が必要なんでしょうか? OS の勉強をすることです。ライブラリ内部の実装は OS 依存部分を含みます。一応、(ANSI 部分は)OS 依存にしないためのライブラリですから。ただし、printf や scanf など大半の関数は単純な関数の組み合わせですので、printf と同じ関数を作ることは簡単に出来ます。単純な関数ほど OS に依存します。 自分で考えて、printf や scanf と同じ関数を作ってみてはどうでしょうか?

jimihenn
質問者

お礼

ありがとうございます。 確かに僕にはまだ早そうです。 とはいえ大体の学習の道しるべにはなりました。

関連するQ&A

  • C言語の標準関数についての質問です><

    C言語の標準関数についての質問です>< 実行結果が以下のようになるようにプログラムを作りたいのですが・・・・ int indat; ← 用意された変数です。 static char outbuf[101]; ←用意された変数です。 使える標準関数は、 sprintf関数と、strlen関数です。 実行結果 数値入力==>123 数値入力==>45 数値入力==>6789 数値入力==>0 数値入力==>-1 文字列連結=123△45△6789△0 自分なりに書きましたが動きません>< #include <stdio.h> #include <string.h> void main(void) { int indat,i; static char outbuf[101]; i=0; while(indat >= 0) { printf("数値入力==>"); scanf("%d",&indat); sprintf(&outbuf[i],"%d",indat); i=strlen(outbuf); } printf("文字列連結",outbuf); return; } 表示の△は空白です>< どなたか、プログラムを教えてください><

  • scanf関数を用いての標準演算子(*/+-%)の入力方法

    C言語超初心者のものです。 scanf関数を用いての標準演算子(*/+-%)の入力方法について質問があります。 例:17 / 5 = 3 において ”17”、 ”/”、 ”5” を各々キーボードから入力し、”3”の数値をDOS画面?上に表示させるものです。 ”17”、”5”はscanf関数を使いキーボードから入力できるのですが、”/”だけがどうしても標準演算子として認識させることが出来ません。 私は以下のプログラムを組んでいるのですが、 char num3;  ・・・(省略) printf("Please type in a operator: "); scanf("%c",&num3);  ・・・(省略) printf("%d %c %d is %d\n", num1, num3, num2, product); 無理やりコンパイルして、DOS画面?上に表示させても17 / 5=65536となってしまいます。 ”/”をプログラミングの中で認識させて、ディスプレイ上で例式が正常に表示されるようにしたいのですが、どうしても回答が3になりません。 多分1つの標準演算子が入力できれば、他の標準演算子も入力できると考えています。 どうすればキーボードから標準演算子をプログラミングに認識させることが可能になるのでしょうか? どなたか分かる方がいらっしゃいましたら教えて下さい。 また参考になるURLなどがあればそれも教えて下さい。 よろしくお願いします。

  • if-else文および標準演算子(*/+-%)の入力方法

    度々失礼します。 C言語超初心者のものです。QNo.3392139(回答してくださった皆さんありがとうございます。)でも質問させていただきましたが、詳細が足りないようなので、 ここで再度質問をさせていただきます。 プログラミング内容 (1)Enter first integer: 17 [好きな数値選択] (2)Enter operator:(*/+-%) [好きな演算子選択] (3)Enter second integer:5 [好きな数値選択] というように数字・標準演算子・数字の順でキーボードから入力し、 (4)17 / 5 = 3 を(1)~(4)までDOS画面?上に表示させるものです。 そして、if-else文を作成して、以下のようにプログラムを組んでみたのですが(標準演算子は”/”を選択するようにしています)、 else文のところで”parse erro before 'else' ”というエラーが出てしまいます。このエラーがなくなれば、プログラムはうまく起動すると思うのですが・・・。 どこが悪いのでしょうか? まあ、超初心者なので、使える言語はint、float、char、そして関数はscanf、if-else文、位です。 int main() { int num1, num2, num4, num5, num6; char chr; printf("Enter the first integer: "); scanf("%d",&num1); scanf("%c",&num5); printf("Enter an operator (* / + - %): "); scanf("%c",&chr); scanf("%c",&num6); printf("Enter the second integer: "); scanf("%d",&num2); if(chr == '/') num4 = num1 / num2; printf("%d / %d = %d\n", num1, num2, num4); else printf("Can not\n"); system("pause"); return 0; } 大変皆さんお忙しいとは思いますが、出来たらお願いします。 査閲ありがとうございます。

  • C言語で、printfのような関数の定義方法

    わかりにくい説明しかできないので例をあげます。 「 PutFormatString 」という関数を定義したとして、 int year = 2009 ; PutFormatString( "今年は%d年です。\n" , year ); を実行すると、関数の内部でprintf文が実行され、 今年は2009年です。 と表示されるようにするためには どのように関数を定義すればよいのでしょうか? printf文とセットで行う処理を何度も書くのが面倒なため、 関数としてまとめようと思ったのですが、行き詰まってしまいました。

  • VBAで関数をつくる

    If文やForNext構文を駆使して階乗、順列、組み合わせの計算を実現する関数を作りたいです。どのように考えてどのようなプログラムを書けばよいか教えてください!

  • 初歩的な質問ですが;;

    学校でC言語を習い始めたのですが、 よく、理解できない部分があるので教えていただけると、ありがたいです。 関数、for文でのことですが 2重のfor文がよく理解できません。 たとえば、略して書きますが for(i = 0;i < 10; i++){ printf("%d",i); for(j = 0; j < i; j++){ printf("*"); } printf("\n"); で、内側のfor文のことで疑問があります。 なぜ、行を繰り返して表示しなければいけないのでしょうか?? 本当、初歩的な質問ですがお願いしますm,,m

  • 再帰関数でポインタのインクリメントがうまくいかない 

    再帰関数で標準出力に文字列を表示するプログラムを書きました。 #include <stdio.h> void display(char *p); int main(void) { display("おちょめちょめ"); return 0; } void display(char *p) { if(*p){ printf("%c",*p); dis(p++); } } 実行するとbがいっぱい出てきます。?? 一番最後のコードですが、()の中を p=p+1 p+=1 p+1 などにするとちゃんと おちょめちょめ と表示されます。なぜでしょうか。

  • プログラムがmain関数から始まらない??

    C言語初心者です。よろしくお願いします。 return文について勉強している途中だったのですが、次のプログラムを実行してみたところ、わからないことが出てきたので質問させていただきました。(ほとんど自分で作ったプログラムではないです) #include <stdio.h> /* 関数a()はintを返すと指定 */ int a() {     if (1) {          /* ここで関数a()は終わります */          printf("yes1\n");          return 300;     }     pritnf("yes2\n");     /* ここは通りません */     printf("this is a()\n");     return 10; } int main() {     int i;     /* 関数a()の返り値を変数iに代入します */     i = a();     printf("i = %d\n", i);     return 0; } このプログラムの出力結果は yes1 i = 300 となるのですが、 1.以前「main関数からプログラムは開始する」というようなことを学習したのですが、このプログラムではyes1が出力されていることからa関数からプログラムが始まっていませんか? 2.a関数のif文の中のreturn 300;でプログラムが終了しないのはなぜですか? 知識のある方、どうか教えてください。 よろしくお願いします。 ※ このプログラムを表示させる際、Tabキー及び半角では適度な空白スペースを作ることができなかったので、プログラムを見やすくするための空白スペースは全て全角スペースで作ってあります。(もしかしたら普通に表示させる方法があるのかもしれませんが、わかりませんでした。)

  • C言語の標準関数についての質問です。

    C言語の標準関数についての質問です。 実行結果が以下のようになるようにしたいのですが・・・ char moji[]="AB$c5kDp9#s*Gz"; ←この二行は用意されている変数です。 int cnt[4]; 実行結果↓ 英大文字:4 ←cnt[0] 英小文字:5 ←cnt[1] 数字文字:2 ←cnt[2] その他:3 ←cnt[3] 使える関数は ・isdigit ・islower ・isupper です。 ↓ 自分で作ったのですがなかなかできません>< #include <stdio.h> #include <ctype.h> void main(void) { char moji[]="AB$c5kDp9#s*Gz"; int cnt[4]={0,0,0,0},flg; cnt=0; while(flg!='\0') { flg=isupper(moji[cnt]); if(flg!=0) { cnt[0]++; } flg=islower(moji[cnt]); if(flg!=0) { cnt[1]++; } flg=flgisdigit(moji[cnt]); if(flg!=0) { cnt[2]++; } else { cnt[3]++; } } printf("英大文字:%d\n",cnt[0]); printf("英小文字:%d\n",cnt[1]); printf("数字文字:%d\n",cnt[2]); printf("その他:%d\n",cnt[3]); return; } プログラムの訂正や、他にどんなプログラムがあるのか見せてもらいたいです>< ちなみに自分のはflgを立てるやり方なのですが、エラーが・・・・。

  • C言語の関数(if文やfor文を含む関数)の定義の仕方

    C言語の関数(if文やfor文を含む関数)の定義の仕方 int WINAPI WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lpC,int nC){ ●● } ↑上記のような形式のウィンドウアプリケーションの場合、 関数の定義はint WINAPI~の前にしておくべきなのでしょうか? 関数の中にif文やfor文を入れようとすると「関数定義のようですが、パラメータ リストがありません。外見上の本体をスキップします。」というエラーが出てしまいます。 int WINAPIの中で定義しようとするとそれはそれで「ローカル関数の定義が正しくありません」というエラーが出てしまいます。 詳しい方がいたらアドバイス願います。 ※関数を使わずにプログラムを組んだことはあるのですが、関数の定義に初挑戦しようとしたところ見事にわけが分からなくなってしまいました。

専門家に質問してみよう