第2回NP資料 Makefile

ネットワークプログラミング
第3回「C言語の基礎~コマンドライン引数・構造体・ポイン
タ」
2009年秋学期
Rodney Van Meter
Last Week’s Excitement
授業Webページ

SFC-SFShttps://vu.sfc.keio.ac.jp/sfcsfs/


本講義を「MY時間割(仮)」へ登録してください
課題・授業資料などの情報を掲示します


課題は毎回こちらに提出!!
今日の課題締め切り


10/20(月)23:59分まで!
遅れて提出する方は要連絡
今期の授業スケジュール(予定)











第1回:イントロダクション
第2回:C言語の基礎~関数・変数・Makefile
第3回:C言語の基礎~コマンドライン引数・構造体・ポインタ
第4回:C言語の基礎~ポインタと配列・リスト構造・file I/O
第5回:ネットワークとプログラミング(1)
第6回:ネットワークとプログラミング(2)
第7回:ネットワークプログラミング実践(1)
第8回:ネットワークプログラミング実践(2)
第9回:応用ネットワークプログラミング(1)
第10回:応用ネットワークプログラミング(2)
第11回以降:ミニプロ
今日のお題




Review last week’s homework
コマンドライン引数
ポインタの基礎
構造体
課題1(2)

argc,argvを用いて引 コマンドライン引数
数を全て出力する。

main( int argc, char **argv)


実行例/出力例
%./a.out 123 456 789
arg[0]: ./a.out
arg[1]: 123
arg[2]: 456
arg[3]: 789




main( int argc, char *argv[])
argc には引数の数
argv[0] にはコマンド名
argv[1] には1番目の引数
argv[2] には2番目の引数
課題2:
Homework Prob. 2
浮動小数点のレーンジ
(fprange.c)
1. 最小: Write a program that starts with
x = 1.0, and divides it by two
repeatedly until it becomes zero
2. 最大: Do the same thing getting larger
until something happens (what
happens?)
3. Do for both “float” and “double”.
課題3


Makefileを作ってください
一行目は:

all: hello size fortest cline numbers
コマンドライン引数
コマンドライン引数:argc,argv

コマンドの引数を用いるには?
% cat –n file
% cat file1 file2 file3
コマンドライン引数の利用法






main( int argc, char **argv)
main( int argc, char *argv[])
argc には引数の数
argv[0] にはコマンド名
argv[1] には1番目の引数
argv[2] には2番目の引数
引数を出力するプログラム
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i=0; i < argc; i++){
printf(“\t%s\n”, argv[i]);
}
return 0;
}
ポインタ
ポインタとは?
アドレス

ポインタ変数

「変数」を指す変数

int i = 10;
int j = 20;
int *ptr

*の意味



「intへのポインタ型」であると宣言
するための指定子
108
i
104
j
100
ptr
0
変数とアドレス
ポインタ変数の操作(1)








int i = 10;
int j = 20;
int *ptr = &i
printf(“i=%d\n”, &i)
printf(“ptr=%d\n”, ptr)
printf(“i=%d\n”, i)
printf(“*ptr=%d\n”,*ptr)
ptrはiをさすポインタ変数
アドレス
108
i
10
104
j
20
100
ptr
108
0
変数とアドレス
ポインタ変数の操作(2)







int x=1, y=5;
int z[10];
int *p;
p=&x; /* pはxを指す */
y=*p; /* yに1を代入 */
*p = 0; /* xが0になる */
p=&z[2]; /* pはz[2]を指す */
ポインタと関数(1)
#include <stdio.h>
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
int main(){
int a = 5;
int b = 3;
swap (a,b);
printf(“a=%d\n”, a);
printf(“b=%d\n”,b);
return 0;
}
int型の変数を入れ替えるプログラム
ポインタと関数(2)
#include <stdio.h>
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
int main(){
int a = 5;
int b = 3;
swap (a,b);
printf(“a=%d\n”, a);
printf(“b=%d\n”,b);
return 0;
}
アドレス
108
a
104
b
94
90
0
交換
x
5
y
3
変数とアドレス
ポインタと関数(3)
#include <stdio.h>
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int main(){
int a = 5;
int b = 3;
swap (&a,&b);
printf(“a=%d\n”, a);
printf(“b=%d\n”,b);
return 0;
}
int型の変数を入れ替えるプログラム
108
a
*x
104
b
*y
交換
94
x
108
90
y
104
0
変数とアドレス
構造体
構造体(structure)

構造体を用いると、複数のデータを1つのまとまりと
して取り扱うことができる

Ex: 1人の学生に対して学籍番号と成績
struct student{
int id;
int score;
};

異なる型も混在できる
struct student2{
char name[32];
int score;
};
構造体の定義

定義の方法
struct 構造体名{
型 メンバ名1;
型 メンバ名2;
:
:
};

使用例
struct student{
int id;
int score;
};
構造体を用いた変数

定義した構造体を用いて変数はプリミティブな
型と同じ方法で宣言できる

型名の変わりにstruct 構造体名を用いる
int a;
struct student b;
構造体メンバへのアクセス(1)

構造体メンバへのアクセスは.(ドット)演算子を
用いる

Ex: struct studentの変数bの点数(メンバ
名:score)を表示する
struct student b = {70000000,70};
printf(“bの点数は%dです\n”, b.score);
構造体メンバへのアクセス(2)

構造体へのポインタの変数のメンバへのアクセスは
->演算子を用いる


Ex: struct studentの変数bの点数(メンバ名:score)を表
示する
struct student b = {70000000,70};
struct student *c = &b;
printf(“bの点数は%dです\n”, c->score);
構造体へのポインタ変数->メンバ名 は
(*構造体へのポインタ変数).メンバ名 と同意
構造体(structure)(使用例1)
int main()
 構造体の定義、
{
構造体変数の宣言
int i;
struct student{
構造体変数の初期化
int id;
を同時に行う場合
int score;
} students[5] = { {70001234,80},
{70204578,70},
{70157384,60},
{70355678,75},
{70207658,49} };
for(i=0;i<5;i++){
printf("student id:%d, score:%d\n",
students[i].id, students[i].score);
}
}
構造体(structure)(使用例2)
struct student{
int id;
int score;
};

構造体の定義を分け
た場合
変数の宣言、初期化
は同時に行っている

Int
main()
{
int i;
struct student students[5] = { {70001234,80},
{70204578,70},
{70157384,60},
{70355678,75},
{70207658,49} };
for(i=0;i<5;i++){
printf("student id:%d, score:%d\n",
students[i].id, students[i].score);
}
}
構造体(structure)(使用例3)
struct student{
int id;
int score;
};

構造体の定義を分け
た場合
初期化は行わずに
代入を行っている。

Int
main()
{
int i;
struct student students[5];
for(i=0; i<5; i++){
students[i].id = i;
students[i].score = i;
}
for(i=0;i<5;i++){
printf("student id:%d, score:%d\n",
students[i].id, students[i].score);
}
}
typedefを用いる
typedef struct student{
int id;
int score;
} STUDENT;
STUDENT students[5];
【補足2】構造体ポインタ
struct student st;
struct student *sp;
sp = &st;
sp->id = 7000123;
(*sp).score = 23;
sp
st
id
score
7000123
23
printf(“%d\n”, sp->score);
練習1:構造体の練習
以下の情報をキーボードから入力し、後でまとめて出力する。
 学籍番号
 ログイン名
 名前
%./a.out 80749423 kazuhisa “kazuhisa matsuzono”

Number: 7045678
Login name: kazuhisa
Name: kazuhisa matsuzono
構造体と関数
#include <stdio.h>
struct student{
char name[20];
int math;
int jlang;
};
void clear(struct student *sei);
int main(){
struct student seito;
/* clearing data in seito */
clear(&seito);
return 0;
}
void clear(struct student *sei){
strcpy (sei->name, “”);
sei->math=0;
sei->jlang=0;
}
課題





Determine size of struct student
Determine size of array of struct
student
Use memcpy() to copy struct
Use assignment to copy struct
Use memset() to clear memory
実習(第2回課題)
1. 2つの整数値を入力し,最小公倍数、最大公約
数を出力せよ


コマンドライン引数で値を2つ指定
つぎのページにヒント
関数を作成すること
2. 2つのint型の変数x,yを受け取り,その和と差
をwa及びsaが指すint型の変数に格納する関数
void calc(int x, int y, int *wa, int *sa)を
作成せよ.
課題2 (numbers.c)
1. 2つの整数値を入力し,最小公倍数、最大公約
数を出力せよ


コマンドライン引数で値を2つ指定
関数を作成すること
2. 2つのint型の変数x,yを受け取り,その和と差
をwa及びsaが指すint型の変数に格納する関数
void calc(int x, int y, int *wa, int *sa)を
作成せよ.
つぎのページにヒント
課題2のヒント

最大公約数を先に求める

ユークリッドの互除法
最小公倍数


n * m / (最大公約数)
実習ヒント

最大公約数を先に求める

ユークリッドの互除法
最小公倍数


n * m / (最大公約数)