カテゴリ:13.実際にやってみる > 13.1 C言語

windows8.1の環境でJavaのプログラミング

■Eclipseを丸ごとインストール
https://blog.codecamp.jp/eclipse

以下、順番に入れていったが、日本語化もうまくいかなかったし、ちょっと面倒。

■1.JDKのダウンロードとインストール
①以下からJava Platform (JDK) をダウンロード
http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html

②ダウンロードしたjdk-10_windows-x64_bin.exeをインストール。特に設定を変える必要はなく、そのまま次へ
③PATHの設定
このままだとJavaの実行ファイルのPATHが通っていないので、PATHの設定をする
「システムのプロパティ」「詳細設定」「環境変数」「システム環境変数」「Path」の先頭に
C:\Program Files\Java\jdk-10\bin
を追記
→うまく動作しなければ、再起動が無難(私は再起動して初めて動いた

■2.Eclipseのダウンロードとインストール
①Eclipse IDE for Java EE Developersをダウンロード
http://www.eclipse.org/downloads/eclipse-packages/
※Java EE

②実行

※日本語化もできるが、うまく行かず。

■3.eclipse.exeを起動

■画面に表示するプログラム (pg.c) 
#include<stdio.h>
int main(){ 
 printf("こんちくは\n");
}

実行結果は以下です。コンパイルして、pgという実行ファイルを作ります。
c:\work>gcc -o pg pg.c
c:\work>pg
こんちくは

順に解説します。
#include<stdio.h> // 標準入出力の関数が定義されたファイルを読み込む
int main(){ //引数が無い(=値を渡さない)関数main関数。
 printf("こんちくは\n"); //「こんちくは」と表示。文字列は""で囲う
}

2行目のintは、戻り値の変数の値の型です。この場合はint(整数)です。

じゃあ、戻り値が無いのにこんなふうにかくの?

→以下で試してみましょう。
main(void){  ⇒エラー
int main(void){  ⇒正常動作
void main(void){  ⇒正常動作
int main(){  ⇒正常動作
void main(){   ⇒正常動作

次に、戻り値の returnを試してみましょう。
returnは、main関数を修了するという意味です。このとき、int mainとして戻り値の型を整数に宣言しています。return 0は、戻り値として0をセットしています。この戻り値ですが、他の関数からこの関数を呼んだ場合、呼び元の関数に戻り値を渡します。 
#include<stdio.h>
int main(){ 
 printf("こんちくは\n");
 returun 0;
}

①returnなし ⇒正常動作
②return;  ⇒voidで宣言すれば、正常動作。intで宣言した場合は、エラー
③return 0; ⇒正常動作。ただし、voidではなく、int mainで開始した場合にのみ。intでは戻値の型を指定しているので、当然といえばそうである。 
④returun19; ⇒正常動作。ただし、voidではなく、int mainで開始

まず、言葉の定義から
・引数:関数に渡す値
・戻り値:関数の処理をした結果、呼び出し元に返す値
・関数(function):サブプログラムとでもいうのでしょうか。値を渡され、その演算をして結果を返す。
たとえば、2つの値、xとyがあって(←xとyが引数)、
それを、hikakuという関数で、大きい値を求めます(←この値が戻り値)

関数の書き方は、以下です。

戻り値の型 関数名(引数)

(例1)一般的な場合(戻り値がある)
  int fact(int n)
  引数:nというint型の値
  戻り値:関数factによる演算結果で、int型
  関数:factという処理。内容は、そのあとの{}で囲まれた中に記載される。
returnで戻り値を返す
 
(例2)戻り値が無い場合
  voidを使う
voidは戻り値が無いという意味です。(returnを使わない、またはreturn 10などと戻り値を入れず、returnのみと記載)。例えば、printfにて表示する。
 
(例3)main関数
void main(){
 メイン関数。

■プロトタイプ宣言
いろいろな処理をする関数を書き、最後にmain関数を書きます。先にmain関数を書いて、後ろにその他の関数を書く場合、関数の型だけを先に宣言しておく必要があります。それをプロトタイプ宣言といいます。

■WindowsでのCの環境
WindowsでCのコンパイル環境(gcc)が欲しいので、以下に従う
http://yohshiy.blog.fc2.com/blog-entry-292.html

MinGW のダウンロード
https://sourceforge.net/projects/mingw/?source=typ_redirect

欲しいのはCのコンパイル環境だけなので
mingw32-base
mingw32-gcc-g++
を選択してInstllationタブからApply Chagesから「apply」
※格安SIMからのテザリングのせいか、結構時間がかかる

PATHの設定をします。システム環境変数のPATHのところを編集して、最後に「;C:\MinGW\bin」を追記

これで完成。再起動は必要なかった。

■コンパイル
コマンドプロンプト(cmd)を起動して、以下のコマンドでコンパイル。
gcc -o test test.c

※テキストでtest.cというファイルを作り、上記コマンドを実行するとtest.exeという実行ファイルが完成する。上記にて、以下のように実行しても結果は同じ
gcc -o test test.c
※拡張子は「.c」である必要あり。「.d」にしてみると、エラーになる。
※文字化けするときは、メモ帳ではなくなんらかのエディタで文字コードを「Shift-JIS」で保存すると治る可能性がある。

こっちの方がわかりやすいかな。
gcc pg1.c -o pg1
※-oで出力するファイルを指定する。指定しないとa.outという名で出力される

■Linuxでc
こちらは環境があるからそのまま実行できる。私はAWSの上で実行した。

①プログラムのソースファイル(pg1.c)を作成
#include<stdio.h>
int main(){
 printf("こんちくは\n");
}

②コンパイル
# gcc pg1.c

すると、a.outというファイルが作成される
# ls
a.out    pg1.c

③ファイルの実行     
# ./a.out
こんちくは

■ドットインストール C言語入門
http://dotinstall.com/lessons/basic_c
とてもわかりやすいVTR。

■メモリのアドレスを表記   
#include<stdio.h>
int main(){
 int a=10; //整数aを定義してaに10を代入
 printf("a=%d\n",a); //aの値を表示
 printf("aのアドレス=%p\n",&a); //aのメモリ上のアドレスを表示
}

実行結果は以下です。
c:\work>pg4
a=10
aのアドレス=0028FF2C

http://sc.seeeko.com/archives/5377814.html

OSのコマンドを実行するプログラム。以下では、system関数を使って、pwdとdirを実行させています。
Linuxで動作させています。

https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b06_04_main.html を参照

■プログラム pg.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
 system(pwd;dir);
}
※argc = argument count (コマンドラインからの引数の数)。argv = argument vector 

コンパイル
#gcc -o pg pg.c
 ※pg.exeとしても結果は同じで、exeファイルが作成される。

■実行および実行結果
#./pg.exe
/home   ←pwdの実行結果
pg.c pg.exe  ←dirの実行結果

Windowsの場合は” ”で囲いましょう
#include <stdio.h>
#include <stdlib.h>

int main()
{
 system("dir");
}

Windows環境にて、IPアドレスを入力してもらい、そのIPアドレスpingを打つプログラム
#include <stdio.h>
#include <stdlib.h>
int main(){
 char sbuff[512];
 char command[1024];
 printf("アドレスを入力してください");
 gets(sbuff);
 // コマンドを合成する
 sprintf(command,"ping %s",sbuff);
 // コマンドを実行する
 system(command);
 return 0;
}

3項演算子とは、以下のように書くことで、スッキリとしたプログラムになります。

条件式 ? 式1 : 式2

条件式の結果がYesならが式1を返し、Noなら式2を返します。

たとえば、以下です。これは、aの方が大きければa、bの方が大きければbになります。
a >= b ? a : b

では、以下のプログラムを書いてみましょう。
---------------------プログラム2---------------------------
aとbの大きい数字を表示するプログラムを作りましょう
----------------------------------------------------------------
➀aとbを入力させます。
②aとbで、大きな値を出力します。
応用情報技術者試験を勉強する成子 

書いてみましたが、自信はありません。




#include<stdio.h>
int main(){
 int a;
 int b;
 printf("aを入力してください:");
 scanf("%d",&a);
 printf("bを入力してください:");
 scanf("%d",&b);
 a >= b ? a:b;
}
さて、結果はどうでしょうか。
c:\work>gcc -o pg3 pg3.c

c:\work>pg3.exe
aを入力してください:5
bを入力してください:4

c:\work>
結果が表示されません。結果を表示するようになっていなからです。以下のようにしましょう。また、intでaとbをまとめています。 int main(int a,int b){ としてもいいです。
#include<stdio.h>
int main(){
 int a,b;
 printf("aを入力してください:");
 scanf("%d",&a);
 printf("bを入力してください:");
 scanf("%d",&b);
 a >= b ? printf("%d\n",a):printf("%d\n",b);
}
今度はうまくいきました。
c:\work>pg3.exe
aを入力してください:5
bを入力してください:4
5

または、関数に引き渡すことも可能です。書いてみませんか?
顔カット3 

書きました。動きましたよ。
main関数からHikakuというaとbを比較する関数を呼びます。
結果をresultに入れて、それを表示します。
#include<stdio.h>
int Hikaku(int a,int b){
 return (a>=b)? a:b;
}
 
int main(int a,int b){
 printf("aを入力してください:");
 scanf("%d",&a);
 printf("bを入力してください:");
 scanf("%d",&b);
 int result;
 result=Hikaku(a,b);
 printf("%d\n",result);
}
ただ、Hikaku関数のa,bとmain関数のa,bは別物です。その関数の中でのみ変数が有効だからです。
よって、分かりやすいように、違う文字にした方がいいでしょう。
少し整形をした完成版がこちら。
#include<stdio.h>
int Hikaku(int x,int y){
 return (x>=y)? x:y;
}
 
int main(){
 int a=0;
 int b=0;
 int result;
 printf("aを入力してください:");
 scanf("%d",&a);
 printf("bを入力してください:");
 scanf("%d",&b);
 result=Hikaku(a,b);
 printf("大きい数字は%d\n",result);
}

以下のように、実行するプログラムに引数をつけて渡す場合があります。
# program.exe 123

ping 10.1.1.1なども、pingコマンドに10.1.1.1を引数としてつけますね。
このとき、int main(int argc,const char *argv)を使います。 →int main(int argc, char *argv[]){ がいいかも 
では、以下のプログラム(arg.c)をコンパイルして実行しましょう。
#include <stdio.h>
int main(int argc, char *argv[]){
 int i;
 for(i=0;i<argc;i++){
  printf("argv[%d]=%s\n",i,argv[i]);
 }
 return 0;
}
※argc = argument count (コマンドラインからの引数の数)。argv = argument vector 
実行結果は、以下のようになります。

c:\pg>arg.exe I am a boy.
argv[0]=arg.exe
argv[1]=I
argv[2]=am
argv[3]=a
argv[4]=boy.

変数の有効範囲について、実際にプログラムを実行しながら確認しましょう。
変数iを以下のようにfuncという関数とmainという2つの関数で定義しています。
どちらは互いに独立しています。

#include <stdio.h>
void func(int i){
 printf("funcでのi=%d\n",i);
}
int main(){
 int i=0;
 func(5);
 printf("mainでのi=%d\n",i);
 return 0;
}

func関数では、main関数の引数5を受け取っています。
main関数では、定義した int i=0が有効です。
なので、同じiでも、全く別物となります。実行結果は以下です。

c:\pg>pg
funcでのi=5
mainでのi=0

このように{}内で宣言した変数はローカル変数です。
一方、外に出すと、このプログラムで利用できるグローバルになります。

応用情報技術者試験を勉強する成子

どっちがお勧めですか?
ローカル変数です。
関数の先頭または、その変数を使用する直前が分かりやすくていいと思います。

■定数
定数は、定まった数なので、変化しない数です。一方の変数は、変化する数です。
定数にはいくつかの種類があり、それぞれ型が決っています。
(1)整数 →int
厳密には、short int(16ビット) とlong int(32ビット)があります。
long型にしたい場合は、末尾に「l」「L」(エル)を付けます。

(2)浮動小数点数 →float、double
いわゆる小数です。小数には固定小数点数と浮動小数点数がありますが、コンピュータでは浮動小数点数を使う方が効率的です。
この点を語ると長いのですが、以下に軽く説明しています。
http://sm.seeeko.com/archives/15877104.html

・単精度浮動小数点数(32ビット)はfloat
・倍精度浮動小数点数(64ビット)はdouble

(3)文字定数 →string
1文字。シングルクォート(')で囲う

(4)文字列定数
文字列。ダブルクォート(")で囲う

■指定子(変数指定子)
・char(文字) ⇒ %c
・int(整数) ⇒ %d  ・・・値を、int型と同じく10進数で表示するという意味。
・char *(文字列) ⇒ %s
・double(小数含む値) ⇒ %lf

・プログラムの例
#include<stdio.h>
void main(){
 int num=123;
 printf("num=%d\n",num);
}
これを実行すると、以下のように、numに入った123という整数型の数字が表示されます。
c:\>pg
num=123
862492bc 

じゃあ、ここで、指定子を整数の%dではなく、
doubleの%ldで指定したらどうなりますか?
やってみましょう。コンパイルはエラーになりませんが、以下のようになっていしまいます。
c:\>pg
num=0.000000

■変数
変数の宣言する場所ですが、関数の先頭または、その変数を使用する直前が分かりやすくていいと思います。
C言語の場合、変数はすべて宣言する必要がある→pythonでは不要
なぜかというと、変数の型を決めて、その型に応じたメモリ空間を確保する必要があるからです。

■コメント
/*  */  複数行のコメントを書く場合、終わりがわかるように*/で終わる
// 1行コメントの場合は、先頭に//をつけるだけ

■代入演算子
a+=1; a=a+1;
a-=1; a=a-1;
http://c-lang.sevendays-study.com/day2.html 表2-5より

■論理演算子
&& →AND (例)a == 0 && b == 0  aが0かつ、bが0ならば
|| → OR (例) a == 0 || a == 1  aが0か1ならば
! →否定  (例)!(a == 0)
http://c-lang.sevendays-study.com/day3.html 表3-2より

■比較(ifなどによる条件分岐)
・aが3以上 
 a>=3
※=は>の後
・aが5と一致するか
 a==5
※a=5は、変数aに5を代入するという意味

・aが3以上かつ、6以下
 a>=3 && n<=6

■switch-case文
switch case
caseの終わりににはbreak;を入れる

■エスケープ記号
\はエスケープ記号を表す(文字入力によるが、表記は「¥」)
\n : 改行 (全角表記もしておきます・・・¥n)

■キーボードからの入力
・スキャンエフで、キーボード入力。この場合は、整数値をaに入れる
 scanf("%d",&a);

※&が必要なので、注意。&をつけるのは、メモリ上のアドレスをつけるときも必要でした。
http://sm.seeeko.com/archives/65925709.html
そうです。これは、メモリ上のアドレスを表しているのです。
なぜ&をつけるかという正確な理由は分かりませんが、入力された文字を、aのアドレスの場所に入れるとイメージしてもらえばいいでしょう。&をつけないと、エラーになったと思います。

■int main(void)
・意味は、「型 関数の名前(引数)」です。
・intは整数型。float、doubleは小数も表せる。floatは7桁、doubleは15桁。⇒基本はdoubleを使おう
・void → 引数が無いので、戻り値が無い(returnが無い)。例えば、printfにて表示する。
・returnは戻り値
・return 0 →深い意味はない。intの整数型の場合、正常終了という意味で0を返している。

■インクルードファイル
#include<stdio.h>
.hはヘッダファイルという意味。cプログラムのファイルであれば.c
stdioは、standart input outputの意味

たとえば、printfやscanfなどの関数の処理内容が、このstdio.hに記載されています。

■printf
fはformatのfらしいが、そういうもんだ、と考えるのが得策でしょう。
pythonではprintという関数なので、わかりやすいよね。

文字を表示するのは簡単です。
 printf("こんちくは");
 
一方、変数を表示するのは、一工夫が必要です。
たとえば、以下のように変数に5を入れたとします。
 int a=5;

いくつかパターンを示します。
 printf('a'); //失敗(×)
 printf(a);   //失敗(×)
 printf("a"); //失敗(×)
 printf(5);   //失敗(×)
 printf("%d\n",a); //成功(○)

■構造体
structで宣言する
以下のサイトが分かりやすい
http://www.isl.ne.jp/pcsp/beginC/C_Language_14.html

■関数について
・名前に関して、大文字と小文字は区別される。
・大文字小文字を変えてしまうと、「warning: implicit declaration of function~」として、そんな関数が無いと怒られます。
・main関数は、必ず小文字。Main やMAINなどにするとコンパイル時にエラーになる。
※変数も、大文字小文字は区別される。
※名前に大文字を使うかどうかなどは、開発方針などで決められていることでしょう。

■キャスト演算子
型を強制的に変換する。
たとえば、int型の整数5をdouble型に変換するには、
(double)5

■配列
・要素数が5で、各要素がint型の配列の宣言
int a[10];

・2次元配列の場合
int a[3][3]
※メモリ上でも3×3=9個の領域が確保される。もちろん、3×3のマトリックスではなく、通常と同じなので、番地的には順にa[0][0],a[0][1],a[0][2],a[1][0]・・・という感じ

---------------------プログラム1---------------------------
円の面積を求めるプログラムを作りましょう
----------------------------------------------------------------
■処理
➀半径を入力
②円の面積を出力

■プログラムの構造
➀変数を定義 r:半径 x:面積
②メイン処理 main
 ・半径を入力させる scanf
 ・円の面積を表示する printf
web1 

とりあえず、作ってみました。
#include <stdio.h>  //おまじない
double main(void){ 
 double r; //円の半径。半径は小数かもしれないのでintではなくdoubleに
 double x; //円の面積。3.14を掛けるので小数にするからdoubleに
 printf("半径rを入力してください:"); //文字を出力
 scanf("%lf", &r); //画面から入力させ、その結果をrに入れる。doubleなので%lf
 x=r*3.14; //円の面積を計算する。
 printf("半径%lfの円の面積は%lfです",r,x); //文字を出力
}
いいと思います。
では、コンパイルしてみましょう。
c:\work>gcc -o pg1.exe pg1.c

c:\work>pg1.exe
半径rを入力してください:3
半径3.000000の円の面積は9.420000です
c:\work>
うまく動きましたね。

2行目のmain関数では、なぜ、以下にしたのですか?
double main(void){
応用情報技術者試験を勉強する成子 

rやxがdoubleだからです。




ここの書き方は、以下です。
 [戻り値の型] [関数名]([引数])
 まず、先頭ですが、処理結果の戻り値(または返り値)の型を指定します。今回は、戻り値がありません。なので、doubleにする必要はありません。そして、引数として、このmain関数に渡される値もありません。
いろいろな書き方をすると思いますが、参考までに、Windowsコンパイル環境では以下でした。
main(void){  ⇒エラー
int main(void){  ⇒正常動作
void main(void){  ⇒正常動作
int main(){  ⇒正常動作
void main(){   ⇒正常動作

まあ、2行目がいいと思います。加えて、double xを定義せずにそのまま計算させましょう。その方がシンプルになります。加えて、下から2行目の最後に改行コード「\n」を入れておきました。
#include <stdio.h> 
void main(void){ 
 double r; //円の半径。半径は小数かもしれないのでintではなくdoubleに
 printf("半径rを入力してください:"); //文字を出力
 scanf("%lf", &r); //画面から入力させ、その結果をrに入れる。doubleなので%lf
 printf("半径%lfの円の面積は%lfです\n",r,r*3.14); //文字を出力
}
うまく動きましたね。

--------------------------------
では、違う書き方をしてみましょう。
■プログラムの構造
①変数を定義 r:半径 x:面積
②メイン処理 main
 ・半径を入力させる scanf
 ・円の面積を表示する printf
③関数 Menseki
 ・x=r*3.14で計算する

ここでは、戻り値を理解するために、Mensekiという関数で面積の計算をしてもらいます。
書いてもらったプログラムが以下です。
#include <stdio.h> 
double Menseki(r){
 double x; //円の面積。3.14を掛けるので小数にするからdoubleに
 x=r*3.14; //面積の計算
 return x; //xを戻り値として返す
}
int main(void){
 double r;
 printf("半径rを入力してください:"); //文字を出力
 scanf("%lf", &r); //画面から入力させ、その結果をrに入れる。doubleなので%lf
 double result;
 result=Menseki(r);
 printf("半径%lfの円の面積は%lfです",r,result); //文字を出力
}
コンパイルしてみましょう。
c:\work>gcc -o pg1.exe pg1.c
pg1.c: In function 'Menseki':
pg1.c:3:8: warning: type of 'r' defaults to 'int' [-Wimplicit-int]
 double Menseki(r){
エラーが出ましたね
double Menseki(r)において、rのタイプが定義されていないことが原因です。引数であっても、double rと定義しましょう。
また、小数点以下の表示が不自然なので、小数点以下を指定しましょう。
%.0lfとすることで、小数点以下が0桁。%.2lfとすることで、小数点以下2桁であることを表します。

でき上ったものは以下です。
#include <stdio.h> 
double Menseki(double r){
 double x; //円の面積。3.14を掛けるので小数にするからdoubleに
 x=r*r*3.14; //面積の計算
 return x; //xを戻り値として返す
}
int main(void){
 double r=0.0;
 double result=0.0;
 printf("半径rを入力してください:"); //文字を出力
 scanf("%lf", &r); //画面から入力させ、その結果をrに入れる。doubleなので%lf
 result=Menseki(r);
 printf("半径%.0lfの円の面積は%.2lfです",r,result); //文字を出力。小数点以下を0桁にするため%.0lf、2桁にするから%.2lf
}
実行すると、以下です。小数点以下がきれいになりましたね。
c:\>pg
半径rを入力してください:5
半径5の円の面積は78.50です

↑このページのトップヘ