[gcc最適化]printfがputs呼び出しに置き換えられる場合がある
C言語には、文字表示のためにprintf関数が有ります。 printfは%指定で変数を書式指定付きで埋め込める高機能な関数ですが、高機能な分、処理が遅いというデメリットもあり、書籍によっては “固定の文字を出すだけであればprintf()の替わりにputs()を使用すべし” というHowToが書かれてたりもします。 と今まで思ってましたが… gccの出力を見ると、時によっては”printfをputs呼び出しに自動で変換してくれる場合がある”ようです。 雰囲気では、printf( “hello\n” );のように、”変数を含…
続きを読む
cygwinで1秒未満のスリープを行う
C言語でプログラムを作成時にスリープ処理を行いたい場合、Cの標準ライブラリ関数だとsleep()関数を使用します。ですが、sleep()関数で指定する値の単位は秒なので、1秒未満のスリープを行う事が出来ません。 Visual C++等、Windows環境だとWin32APIにSleep()というものがあり、ミリ秒単位でのスリープが行えるのですが、cygwinでもこの関数が使用できるようです。 #include<stdio.h> #include<windows.h> int main() { printf( "t…
続きを読む
[C言語]getchar()関数は,1文字入力する毎に処理が走る訳ではない
C言語の入門書を見るとgetchar()関数の説明として、”キーボードから1文字入力を読み取る”と書かれていることが多いです。 下記のプログラムは、getchar()の動作確認用プログラムなのですが、実行してみると”キーボードから1文字入力を読み取る”という説明とは異なり、若干の違和感があります。 #inculde <stdio.h> int main( void ) { int data; while( 1 ) { // 1文字入力 data = getchar(); if ( data == EOF )…
続きを読む
74HC4511とBQ-N516RDで,4桁の7セグLEDをコントロールする
7セグのLEDであるBQ-N516RDと、BCDから7セグLED用デコーダICの74HC4511を組み合わせて、PIC等のマイコンからLED表示を行わせる回路を作成します。 今回は、PIC部分後回しにして、BQ-N516RDと74HC4511の仕様とピンアサインをチェックします。 まずは価格のチェックです。 どちらもマルツパーツ館で購入できます(ネットからも買えます) BQ-N516RD 7セグメントLED(4桁・赤・カソードコモン) 472円/個 74HC4511 BCD-to-Seven Segment Latch/Decoder/Driver 157円/個 それでは、各パーツのスペックを…
続きを読む
[C言語]switch文のcase句の後にスペースが必要な場合/不要な場合
人が書いたプログラムを見ていたとき、switch文のcase句の書き方に違和感があるコードが有りました。 要点だけ抜粋すると、以下の内容です。 switch( data ) { … case’1′: // <- caseと’1’の間に空白がない!! … break; case’2′: … break; default: … break; } switch( data ) { … case’1′: // <- caseと’1’の間に空白がない!! … break; case’2′: … break; default: .…
続きを読む
[C言語入門]単純作業を繰り返しさせるためにfor文を使う
前回のプログラムでは、if文やswitch文を使って処理を分岐させる方法を学びました。 今回は、繰り返し処理を説明します。 プログラム言語において、繰り返し処理は、ループ処理とも呼ばれています。 コンピュータは大量の処理/データを、繰り返し作業させるのが得意です。 人とは違ってコンピュータは、どんなに大量のデータであっても途中であきらめずに作業してくれますし、途中で集中力が途切れて間違えてしまう事も有りません。 そんな繰り返し処理ですが、C言語に限らず、プログラムでのループ処理には大きく分けて2つのパターンがあります。 1.指定した回数繰り返す 2.指定した条件が満たされるまで繰り返す1.指定…
続きを読む
[C言語入門]複数の分岐をswitchでシンプルに記述する
前回、if文による処理の分岐を説明しました。 C言語によるプログラムではifさえあればあらゆる分岐は記述できるのですが、場合によってはifの羅列では分かり辛くなってしまう場合も有ります。 例えば、以下のようにメニューを用意し入力値を判定させる場合、比較対象は常にdataであるにも関わらず、毎回”data ==”を書かなければなりません。無駄な表記があると書き間違いが発生しやすくなりますし、ソースコードも見づらくなります。 #include <stdio.h> int main() { int data; …
続きを読む
[gcc]前置インクリメントと後置インクリメントで生成されるアセンブラコードの違い
今回のお題: 以下の文脈で、前置インクリメントと後置インクリメントを行った。 生成されるアセンブラコードは、iとjでどう変わるのか? #include <stdio.h> int main() { int i = 0; int j = 0; for ( i = 0, j = 0; i < 5 ; ) { printf( "ptn2 i = %d, j = %d\n", ++i, j++ ); } return 0; }#incl…
続きを読む
[C言語]printfの後の入力待ちで入力バッファがクリアされる理由
C言語の入門者向けに書かれた書籍を見ると、以下のようなプログラムが良く有ります。 #include<stdio.h> int main() { int value; printf( "数字を入力して下さい:" ); scanf( "%d", &value ); printf( "入力値は%dです\n", value ); return 0; }#include<stdio.h> int main() { i…
続きを読む
gdbによるデバッグのチュートリアル その2
前回の続きです。 gdbによるデバッグのチュートリアル その1 今回は、レジスタ値の確認方法と、Intelアーキテクチャにおけるスタックの使用方法をみていきます。 レジスタ一覧はinfo registerで確認できます。 (gdb) info register eax 0x14 20 ecx 0xbffff924 -1073743580 edx 0xbffff8b4 -1073743692 ebx 0x2a8ff4 2789364 esp 0xbffff860 0xbffff860 ebp 0xbffff888 0xbffff888 esi 0x0 0 edi 0x0 0 eip 0x8048…
続きを読む
gdbによるデバッグのチュートリアル その1
gccで作ったC言語のプログラムを、gdbコマンドを使用してデバッグしてみます。 今回の実験環境は以下の通り。 linux環境でテストしてますが、cygwinでも問題なく動作するはずです… $ gcc –version gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 $ gdb –version GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08 $ uname -a Linux linuxmint 3.0.0-12-generic #20-Ubuntu SMP Fri …
続きを読む
[C言語入門]処理の内容をif文で分岐させる
前回までのサンプルで確認したように、C言語のプログラムは基本的に上から書いた順に関数が実行されていく形で動作します。 一連の作業を順に行うだけならこれで構わないのですが、プログラムによっては状況に応じて処理を分岐したい場合も出てきます。 このような場合は、if文による処理分岐を行います。 というわけで、今回のサンプルはこちらです。 点数を入力し、60点以上なら合格、60点未満なら不合格と表示するプログラムです。 #include <stdio.h> int main() { int score; printf( &quo…
続きを読む
[gcc]if文と3項演算子では,出力されるコードが異なる
gccのアセンブラ出力を見ていて気になったのでメモ。 C言語ではif文を使わなくても、3項演算子を使用して条件分岐を “( a > b ) ? a : b”のような感じで書く事が出来ますが、両者の書き方で生成されるコードが異なるようでした。 3項演算子を使用した場合(test01.c) #include <stdio.h> int sum( int a, int b ); int main() { int a = 10; int b = 10; int result; result = &…
続きを読む
ラッチとフリップフロップの違い
論理回路では、入力信号の状態を保持したい場合がある。 このような場合の最もプリミティブな機構として、ラッチやフリップフロップがある。 RSラッチ 1ビットの状態保持を行う事ができる。 入力状態が直ぐに出力へ反映される。 RとSを同時にアサート状態にすることは出来ない。 Dラッチ RSラッチと基本的に同じで1ビットの状態保持を行う事ができるが、ゲートピンがEnableの時のみ出力が変更される。 Dフリップフロップ CK信号が立ち上がりのタイミングの入力を保持する。 同期式回路を組むときに使う。 現実は電子的な遅延があるので、実際はCK信号のちょっと前(セットアップ時間)から入力を安定させておき、…
続きを読む
[C言語入門]変数が保持できる値の範囲について
変数の宣言 今回のサンプルでは、”int result”ということで、整数型の変数resultを定義しました。 変数として宣言できるのは,int以外にも以下のデータ型があります。 char 主に文字を格納するのに使用 int 主に整数を格納するのに使用 float 主に大きくない実数値を格納するのに使用 double 主に大きな実数値を格納するのに使用char 主に文字を格納するのに使用 int 主に整数を格納するのに使用 float 主に大きくない実数値を格納するのに使用 double 主に大きな実数値を格納するのに使用 また、intに関してはshort,longの接…
続きを読む
[C言語入門]計算した値を変数に保存する
前回は、指定された値を単に印字するだけのプログラムを作成しました。 コンピュータは日本語だと”電子計算機”と呼ばれるぐらいなので、今回は計算処理を行うプログラムを作成してみます。 今回のプログラムは以下の通りです。 #include <stdio.h> main() { int result; result = 10 + 20; printf( "result is %d\n", result ); }#include <stdio.h> main…
続きを読む
[C言語入門]printfの書式指定
前回のサンプルでは、printfの引数に%dを指定する事で、int型の変数値を表示させていました。 この%dの事を書式指定子(conversion specifier)と呼びます。 よく使用される書式指定子には以下のものがあります。 %の後に変換文字を書く事で表示方法を指定できます。 %d 整数を表示させる %s 文字列を表示させる %c 指定された文字コードに対応する,ASCII文字を1文字分表示させる %f 浮動小数点の値を表示(doubleまたはfloat) %d 浮動小数点の値を表示(double) %x 16進数で値を表示 %g 数字を指数表現で表示 %p ポインタ変数…
続きを読む
[C言語入門]画面にメッセージを表示させてみる
文法とか細かいことは置いといて、プログラムを1つ作ってみます。 作業は、windowsにインストールしたcygwin環境で行います。 まず、下記のファイルをエディタで作成します。 #include <stdio.h> main() { printf( "hello world\n" ); }#include <stdio.h> main() { printf( "hello world\n" ); } 作ったファイルは、以下のフォルダに保存してください。 (usernameの部分…
続きを読む
[cygwin]gccで作ったプログラムで,日本語が文字化けする
windowsのcygwin環境にてgccでプログラムを作成した場合、日本語が文字化けする場合があります。 これは、C言語のソースファイル(.cファイル)と、使用しているターミナルの文字コードが一致していないのがよくある原因です(ターミナルというのは、Cygwin Terminal/xterm/コマンドプロンプトetcの事で、いわゆるコマンドを打ち込む”黒い画面”の事です)。 対処法は、プログラムを保存する際に.cファイルの文字コードをutf-8で保存すれば、正しく出力できます。 現在保存されいるソースファイルの文字コードは、fileコマンドで確認できます。 $ fil…
続きを読む
[パタヘネ:読書メモ]第5章 容量と速度の両立:記憶階層の利用 その3
5.4 仮想記憶 仮想記憶を使う目的は主に2つある 複数プログラム間でメモリを効率よく使用する 主記憶以上のメモリ空間を(仮想的に)プログラムが使用できるようにする複数プログラム間でメモリを効率よく使用する 主記憶以上のメモリ空間を(仮想的に)プログラムが使用できるようにする 後者は、仮想アドレスと物理アドレスの変換機能と、他プロセスから自プロセスのメモリ空間をアクセスされないための保護機能がある。 基本的に仮想記憶とキャッシュは同じ考え方だけど、歴史的な経緯により用語がそれぞれで異なっている。 キャッシュミスのことは、仮想記憶の世界ではページフォールトと呼ばれる。 ページフォールが起きるとペ…
続きを読む