Dump file

Published by:

DUMP で出力された内容を ダンプリスト と呼ぶ

ダンプリスト左端はアドレス(ファイル先頭からの位置)

ダンプリスト中央にある16進数(バイト)が列挙されてる部分がマシン語プログラム(バイトコード)を表している。

ダンプリスト右端は、バイトコードをキャラクタコードで表現したときの内容。ただしバイトで表現可能な数値はキャラクタコードの範疇を超えることがあるため、そのような場合はピリオドで表現される。

dump.c

#include <stdio.h>
int main(int argc, char* argv[])
{
    FILE *fp;
    unsigned char buf[16];   /* 読み込みバッファ */
    unsigned long addr = 0;  /* 先頭からのアドレス */
    int readnum, i;

    if(argc <= 1) {
        printf("usage:dump filename\n");
        return 1;
    }
    if(!(fp = fopen(argv[1], "rb"))) {
        printf("file open error.\n");
        return 1;
    }
    while(1) {
        printf("%08x ", addr);
        readnum = fread(buf, 1, 16, fp);
        /* パイナリデータの表示 */
        for(i = 0; i < readnum; i++) {
            if( i == 8)
                 printf("   ");
            printf("%02x ", buf[i]);
        }
        for(i =readnum; i < 16; i++) {
            if(i == 8)
                printf("   ");
            printf("   ");
        }
        printf("   ");
        for(i = 0; i < readnum; i++)
            printf("%c", (32 <= buf[i] && buf[i] <= 126) ? buf[i] : '.');
        printf("\n");
        addr += 16;
        if(feof(fp))
            break;
    }
    fclose(fp);
    return 0;
}

 

 

[GCC]C Compiler on Linux

Published by:

C言語の最小限の開発環境を作る手順

  1. エディタをインストール
  2. コンパイラをインストール
  3. コンパイラにPATHを通す設定をする

エディタをインストール

Atomという新世代のエディター(Windows、Mac OS X、Linux対応)をインストールしてください。

公式サイト

コンパイラをインストール

LinuxでのC言語開発環境について解説しています。「GNU Compiler Collection」が一般的です。

それでは gcc をインストールしていきます。

Debian

Debianでは、apt-getコマンドを使ってgccをインストールします。

# apt-get install gcc

Ubuntu

UbuntuはDebianベースのディストリビューションなので、Debianと同じようにa apt-getコマンドを使います。ただ、Ubuntuにはrootユーザーという概念がないので、sudoコマンドでインストールしていきます。

$ sudo apt-get install gcc

CentOS

CentOSでは、yumコマンドを使ってgccをインストールします。

# yum install gcc

以上で、コンパイラ(gcc)のインストールは完了です。

コンパイラにPATHを通す設定をする

不要です。

ソースコードコンパイル

C言語プログラムのファイル名を「hello.c」というファイルを作成します。ファイルの中身は「Hello, World!」という文字列を出力するプログラムです。

hello.cをコンパイルします。

$ gcc hello.c 

エラーが表示されなければ、OKです。

プログラムの実行

実行します。

$ ./a.out 
Hello, World

無事に実行できましたね。

[GCC]C Compiler on Windows

Published by:

WindowsでgccをインストールするにはMinGWを利用した、C言語の最小限の開発環境を作る手順

  1. エディタをインストール
  2. コンパイラをインストール
  3. コンパイラにPATHを通す設定をする

エディタをインストール

AtomVSCodeなど新世代のエディター(Windows、Mac OS X、Linux対応)をインストールしてください。

コンパイラをインストール

C言語コンパイラって幾つかありますが、visual studioはファイルサイズがデカいので却下です。gccのインストールをオススメします。gccはMacでもLinuxでもWindowsでも使えます。

コンパイラの違い一覧

システム mingw-jp Visual Studio .net Borland C++ Builder
コンパイラ名 gcc cl bcc32
オブジェクトファイルの拡張子 .o .obj .obj
実行ファイル名指定 -o ファイル名 -o ファイル名 -eファイル名
make コマンド mingw32-make nmake make
依存ファイルマクロ $^ $** $**

 

WindowsでgccをインストールするにはMinGWというソフトを使う必要があります。

MinGW | Minimalist GNU for Windows

  1. MinGWのホームページで「Downloads」をクリック
  2. sourceforgeというサイトに飛びます
  3. 「Download mingw-get-setup.exe (86.5 kB)」をクリック
  4. exeファイルをダウンロード
  5. ダウンロードしたexeファイルを起動
  6. インストール自体は「Install」ボタンとか「Continue」ボタンをクリックするだけ

MinGW インストールマネージャー画面 4

左のメニュー画面で「Basic Setup」を選択し、

  • mingw-developer-toolkit
  • mingw32-base
  • mingw32-gcc-g++
  • msys-base-32

を選んで、右クリックで「Mark for Installation」を選択します。

選び終わったら、上の「Installation」メニューから「Apply Changes」を選択すればインストールが始まります。

インストールが始まると、先ほど選択したパッケージがこのように変わります。

MinGW インストールマネージャー画面 5

これでGCCが使えるようになりました。

コンパイラにPATHを通す設定をする

事前にgcc.exeの場所を探しておいてください。
MinGWをインストールする際に設定を変更していなければ C:MinGWbin にあるはずです。

  • エクスプローラー起動
  • マイコンピューターで右クリック
  • プロパティ選択
  • システムの詳細設定
  • 「環境変数」ボタン
  • ユーザー環境変数 or システム環境変数にPathがあります
    そのPathの最後に ;C:¥MinGW¥bin を追記
    ※「;」を必ず付けてください

環境変数画面

ユーザー環境変数とシステム環境変数の違い

  • ユーザー環境変数:今ログインしているユーザーだけに有効
  • システム環境変数:全てのユーザーに有効

お好きな方をお使いください。

コマンドプロンプトで gcc --help と打ってみてください。

↓こんな感じのものが出てればgccが正常に使える状態です。

 

バージョンの確認

> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/5.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-5.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --prefix=/mingw --disable-win32-registry --target=mingw32 --with-arch=i586 --enable-languages=c,c++,objc,obj-c++,fortran,ada --enable-static --enable-shared --enable-threads=posix --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --enable-libstdcxx-debug --with-tune=generic --enable-libgomp --disable-libvtv --enable-nls
Thread model: posix
gcc version 5.3.0 (GCC)

 

ソースコードコンパイル

C言語プログラムのファイル名を「hello.c」というファイルを作成します。ファイルの中身は「Hello, World!」という文字列を出力するプログラムです。

以下のコマンドを打ってみてください。

> gcc hello.c -o hello.exe

そしたら hello.exe が作られています。

プログラムの実行

コマンドプロンプトで実行ファイル名を入力してEnterキーを押すだけです。

コマンドプロンプトで、「hello.exe」を実行します。

> hello.exe
Hello, World

このように「Hello, World」という文字列が出力されれば、OKです。

実行ファイルを指定した場合、指定したファイルを実行してください。

参考:

C exercises2 (3) structures

Published by:

演習

1)任意二つのunsigned int型数値の論理AND, OR, XORを求めなさい(P324)

/* a9-4-1.c */
#include <stdio.h>
#include <limits.h>

int main(void)
{
  unsigned a, b;

  printf("0 〜 %u の整数を2つ入力してください。¥n", UINT_MAX);
  printf("> ");
  scanf("%u", &a);
  printf("> ");
  scanf("%u", &b);

  printf("%u(%#x) AND %u(%#x) = %#x¥n",__,__,__,__,__);
  printf("%u(%#x) OR  %u(%#x) = %#x¥n",__,__,__,__,__);
  printf("%u(%#x) XOR %u(%#x) = %#x¥n",__,__,__,__,__);

  return 0;
}

 

2)任意unsigned int型数値のビットパターンを表示(P328)

/* a9-4-2.c */
#include <stdio.h>
#include <limits.h>

void show_bit(unsigned dt);

int main(void)
{
  unsigned a;

  printf("0 〜 %#x の16進数を入力してください。> ", UINT_MAX);
  scanf("%x", &a);

  show_bit(a);

  return 0;
}

/*** ビット表示関数 ***/
/*(仮引数)dt:表示データ */
void show_bit(unsigned dt)
{
    int i, len;

    len = sizeof(dt) * CHAR_BIT;
        
    printf("%#x ---> ", dt);
    for (i = len - 1; i >= 0; i--){
        putchar(( __ >> __ & 1U) ? '1' : '0' );
    }
    putchar('¥n');
}

 

演習解説

構造体の変数

構造体とは

構造体とは,「いろいろな種類の互いに関連するデータをまとめて, 1つのかたまりにしたもの」である。 たとえば,「氏名,年齢,性別などのデータを一人分だけまとめたもの」 このようなものをいう。

構造体 構造体を構成する要素を,構造体のメンバと呼ぶ。上の例では, 「名前」「性別」「年齢」「身長」「体重」などが,メンバにあたる。

構造体の宣言

構造体は,一つのデータ型であり,その型枠をまず始めに宣言する必要がある。 そして,その型枠を型とする変数を宣言する形で構造体の実体(オブジェクト)を宣言し, それを使用することができる。

構造体の型枠の宣言と,その型枠をもつ構造体変数の宣言は次のようになされる.

struct 構造体タグ名 {メンバの並び};   /* 型枠の宣言 */

struct 構造体タグ名 構造体変数名;     /* 構造体変数の宣言 */

例えば,次図のような人のデータをまとめた構造体の定義は下のようになる。

person 構造体struct

 _person {           /* _person がタグ名 */
    char name[20];        /* 文字配列型のメンバ name */
    char sex;              /* 文字型メンバ sex */
    int age;               /* 整数型メンバ age */
    double height;         /* 倍精度実数型メンバ height */
    double weight;         /* 倍精度実数型メンバ weight */
};


struct

 _person p;      /* p という名前の struct _person 型変数を宣言 */

構造体の代入

一つの構造体変数の内容全部を 同じ型の別の構造体変数に, 通常の変数を代入するのと同じように,代入することができる.

    person_t p1 = {"Tom", 'M', 19, 175.2, 69.5};
    person_t p2;
    
    p2 = p1;

構造体の代入

構造体の配列

構造体を並べた配列も扱える.その宣言定義は通常のようにすればよい.

#define PERSON_NUM 5

typedef struct {   
    char name[20];
    char sex; 
    int age;
    double height; 
    double weight; 
} person_t;

person_t p[PERSON_NUM]

;

これで,要素数がPERSON_NUM個(5個)の person_t 構造体型配列 p ができる.

構造体配列たとえば,上の図で色のついてある p[3] の height メンバには, p[3].height でアクセスする.

サンプルプログラム2

#include <stdio.h>

#define PERSON_NUM 5

typedef struct {   
    char name[20];
    char sex; 
    int age;
    double height; 
    double weight; 
} person_t;

main()
{
    person_t p[PERSON_NUM] = {{"Bob",      'M', 19, 165.4, 72.5},
                              {"Alice",    'F', 19, 161.7, 44.2},
                              {"Tom",      'M', 20, 175.2, 66.3},
                              {"Stefany",  'F', 18, 159.3, 48.5},
                              {"Leonardo", 'M', 19, 172.8, 67.2}};
    int i;
    double height_sum, weight_sum, height_ave, weight_ave;                          
    
    height_sum = weight_sum = 0.0;
    for (i = 0; i < PERSON_NUM; i++) {
        height_sum += p[i].height;
        weight_sum += p[i].weight;
    }
    height_ave = height_sum / PERSON_NUM;
    weight_ave = weight_sum / PERSON_NUM;
    
    printf("average height = %fn", height_ave);
    printf("average weight = %fn", weight_ave);
    
    return 0;
}

構造体のいろいろな宣言の仕方

  1. 構造体の型枠と実体を同時に宣言する
  2. 初期化も同時に行う
  3. 構造体タグ名を記述しないこともできる
  4. typedefで別名をつけることができる

演習

「学籍番号、氏名、学年、クラス」を含める構造体の宣言、初期化、表示するプロフラムを作る。
演習
struct student
{
char no[10]; //番号
char name[20]; //名前
int s_year; //年
char s_class; //クラス
};

C programming 2 (3) Arrays 2

Published by:

ハッカソン

ハッカソン(英語: hackathon 、別名:hack day ,hackfest ,codefest )とはソフトウェア開発分野のプログラマやグラフィックデザイナー、ユーザインタフェース設計者、プロジェクトマネージャらが集中的に作業をするソフトウェア関連プロジェクトのイベントである。

ハッカソン – Wikipedia

https://ja.wikipedia.org/wiki/ハッカソン

国内最大級のITコンテスト「JPHACK 2016」のお知らせ
——————————————————————————

こんにちは!JPHACKS運営事務局です。

突然ですが、モノづくりを仕事にしたいと考えているデザイン系、情報系学生のみなさん、
こんなお悩みはありませんか?

・「学生のうちに、アプリやプロダクトなど何か一つ形にしておきたい」
・「ただ、自分は○○はできるけど、△△ができないから、Webサービスやアプリをつくれない」
・「同世代のデザイン系学生、情報系学生と競い合い、交流したい」
・「自分のスキルがどの程度のものか確かめたい。有名企業の社会人からレビューを受けてみたい」

そんなお悩みを解決すべく今回ご紹介させていただくのが、「JPHACKS 2016」です。

http://jphacks-civic.strikingly.com/

JPHACKS2016 エントリーの歩み:

  1. JPHACKS2016 エントリー
  2. JPHACKS2016 本エントリー
    1. URL: http://ubi.daiichi-koudai.com/ – ユビキタス・クラブ
    2. github: https://github.com/
  3. JPHACKS2016追加エントリー

前回の演習

  • 演習5-4(p115) List5-6を書き換えて、配列aの要素の並びを逆順にしたものをbにコピーするプログラムを作成さよ。
#include <stdio.h>
#define NUMBER 5

int main(void)
{
    int i;
    int va[NUMBER] = {15, 20, 30};
    int vb[NUMBER];
    
    for(i = 0; i < 5; i++) {
        vb[i] = va[NUMBER - i - 1];
    }
    
    puts(" va vb");
    puts("-------");
    
    for(i = 0; i < 5; i++) {
        printf("%3d%3d\n", va[i], vb[i]);
    
    }
    
    return(0);
}

 

二次元配列の宣言

配列には同じデータ型の値を要素として管理できますが、配列そのものを要素として持つ配列を作成することが出来ます。何次元でも出来ますがよく利用される2次元を例に考えてみます。

2次元配列の書式は次の通りです。

データ型 配列名[要素数1][要素数2];

配列と単に書いた場合は1次元の配列です。1次元の配列の場合は「配列名[添字]」でそれぞれの要素を表しますが、2次元の場合は「配列名[添字][添字]」で各要素を表します。

具体的には次のように記述します。

int seiseki[2][3];

seiseki[0][0] = 72;
seiseki[0][1] = 67;
seiseki[0][2] = 84;

seiseki[1][0] = 67;
seiseki[1][1] = 92;
seiseki[1][2] = 71;

2次元配列を使う意味を考えてみます。例えば6日間の運動した時間を管理するのではあれば1行に列挙して管理するのが便利ですし、3教科の成績を2人分管理するのであれば表形式で管理した方が便利です。成績と名前などのように2つの異なるインデックスを使って要素を特定した方が便利な場合には2次元配列が有効です。

なお今回は2次元の例でしたが3次元でも4次元でも可能です。その場合は次のような書式となります。

データ型 配列名[要素数1][要素数2][要素数3];
データ型 配列名[要素数1][要素数2][要素数3][要素数4];

3次元までは利用することもありますが、4次元以上の多次元配列ともなるとあまり利用する機会はありません。

二次元配列の初期化

二次元配列の場合でも宣言と同時に初期値を設定することが出来ます。次の書式を使います。

データ型 配列名[要素数1][要素数2] = {{値00, 値01, ...}, {値10, 値11, ...}, ...};

少し分かりにくいですが上記は次のように記述したものと同じです。

データ型 配列名[要素数1][要素数2];

配列名[0][0] = 値00;
配列名[0][1] = 値01;
...


配列名[1][0] = 値10;
配列名[1][1] = 11;
...

...

要素数2の配列があたかも1つの要素のように、要素数1の分だけあるような形で指定します。具体的には次のように記述します。

int seiseki[2][3] = {{72, 67, 84}, {67, 92, 71}};

この場合は次のように記述した場合と同じです。

int seiseki[2][3];

seiseki[0][0] = 72;
seiseki[0][1] = 67;
seiseki[0][2] = 84;

seiseki[1][0] = 67;
seiseki[1][1] = 92;
seiseki[1][2] = 71;

要素数を指定せずに初期化する

配列は宣言と同時に初期化する場合は要素数を省略できました。2次元配列の場合でも最初の配列の要素数は省略が可能となっています。

データ型 配列名[][要素数2] = {{値00, 値01, ...}, {値10, 値11, ...}, ...};

具体的には次のように記述します。

int seiseki[][3] = {{72, 67, 84}, {67, 92, 71}};

二次元配列のデータの利用

では簡単なサンプルプログラムを作成して試してみます。

test5-1.c

#include <stdio.h>

int main(void){
  int seiseki[][3] = {
    {72, 67, 84}, 
    {67, 92, 71}
  };
  int i;

  for (i = 0 ; i < 2 ; i++){
    printf("%d人目の成績です¥n", i + 1);
    printf("算数の点数は%dです¥n", seiseki[i][0]);
    printf("国語の点数は%dです¥n", seiseki[i][1]);
    printf("社会の点数は%dです¥n", seiseki[i][2]);
  }

  return 0;
}

上記を「test5-1.c」の名前で保存し、実行します。

演習

test5-1.cを修正して、科目ごとの合計点を求めてください。

出力例:

算数の合計点:289
国語の合計点:293
社会の合計点:292