今日やること
基礎演習3 C言語の基礎(3)
第09回(2010年06月23日)
先週の復習
算術演算
型変換とキャスト
構造化プログラミング
メモリとポインタ
先週の内容
先週の復習
C言語のファイル
リファレンスの読み方
変数
配列
printf の使い方(1)
3/59
配列 その2
多次元配列
配列に値を代入・参照したい場合は、
配列名[番号]
のようにします。
#include<stdio.h>
main(){
int t[10];
t[2]=2;
t[5]=t[2];
}
t[0] t[1] t[2] t[3] t[4] t[5] t[6] t[7] t[8] t[9]
1
1
配列を宣言するとき、次のように
配列名[番号][番号]
[番号]を複数つけることにより、多次元配列を利用できます。
#include<stdio.h>
main(){
int t[5][5];
t[2][3]=2;
t[4][1]=t[2][3];
}
t[0][0] t[0][1] t[0][2] t[0][3] t[0][4]
t[1][0] t[1][1] t[1][2] t[1][3] t[1][4]
t[2][0] t[2][1] t[2][2] t[2][3] t[2][4]
2
t[3][0] t[3][1] t[3][2] t[3][3] t[3][4]
t[4][0] t[4][1] t[4][2] t[4][3] t[4][4]
2
算術演算 その1
C言語では、様々な演算子が使用できる。
算術演算子:
論理演算子:
x + y : x と y の和
A && B :AかつB
x - y : x と y の差
A || B :AもしくはB
x * y : x と y の積
x / y : x を y で割った商
x % y : x を y で割った余り
関係演算子:
x < y : x < y のとき真(1)、さもなければ偽(0)
x <= y : x <= y のとき真(1)、さもなければ偽(0)
x > y : x < y のとき真(1)、さもなければ偽(0)
x >= y : x > y のとき真(1)、さもなければ偽(0)
x == y : x = y のとき真(1)、さもなければ偽(0)
x != y : x != y のとき真(1)、さもなければ偽(0)
算術演算
7/59
演習:算術演算 (1)
算術演算 その2
インクリメントとディクリメント
インクリメント → 増加
ディクリメント → 減少
A)
B)
C)
D)
x++ : xの値を評価後、インクリメント
++x : xの値をインクリメント後、評価
x-- : xの値を評価後、ディクリメント
--x : xの値をディクリメント後、評価
#include<stdio.h>
#include<stdio.h> それぞれの行が実行されたとき、
main(){
main(){
int
int x,y;
x,y;
例:
A)
B)
C)
D)
y=x++ : y=x; x=x+1; : 値を渡してから、xに1を加える
y=++x : x=x+1; y=x; : xに1を加えてから、値を渡す
y=x-- : y=x; x=x-1; : 値を渡してから、xから1を引く
y=--x : x=x-1; y=x; : xから1を引いてから、値を渡す
}}
変数の値がどうなるか、記入しましょう。
実行してみましょう
x
y
?
?
x=2+3;
x=2+3;
printf("001
printf("001 ->
-> %d¥n",x);
%d¥n",x);
y=x++;
y=x++;
printf("002
printf("002 ->
-> %d
%d %d
%d ¥n",x,y);
¥n",x,y);
y=++x;
y=++x;
printf("003
printf("003 ->
-> %d
%d %d
%d ¥n",x,y);
¥n",x,y);
演習:算術演算 (2)
#include<stdio.h>
#include<stdio.h>
main(){
main(){
int
int x,y;
x,y;
}}
実行してみましょう
型変換とキャスト
x=2+3;
x=2+3;
printf("001
printf("001 ->
-> %d¥n",x);
%d¥n",x);
y=x++;
y=x++;
printf("002
printf("002 ->
-> %d
%d %d
%d ¥n",x,y);
¥n",x,y);
y=++x;
y=++x;
printf("003
printf("003 ->
-> %d
%d %d
%d ¥n",x,y);
¥n",x,y);
12/59
型変換(1)
型変換(2)
次のようなプログラムの場合……。
#include<stdio.h>
#include<stdio.h>
int
int i;
i;
double
double d;
d;
main(){
main(){
i=2;
i=2;
d=i;
d=i;
printf("%f¥n",d);
printf("%f¥n",d);
}}
double型の変数に
整数型の変数iの値を
代入している!
C言語では、自動的に型変換が行われる。
型の違う変数へ代入。
double の変数に int を代入等。
関数の引数として、異なる型の値を代入。
pow(x,y)のxとして整数値を渡す等。
大丈夫。
C言語では、自動的に型変換を行い、
代入してくれます。
今回も、double型の変数dには
2という値が代入されます。
できる限り、情報を失うことがないように変換する。
int から double や、float から double は、情報を
失うことなく、きちんと変換する。
double から int や double から float は、変換する
際に情報が欠落する。
13/59
14/59
強制的な型変換(キャスト)
計算結果の型
強制的に型変換を行うこともできる。
(型名)を、変数や値につける。
#include<stdio.h>
#include<stdio.h>
int
int i;
i;
double
double d;
d;
main(){
main(){
i=2;
i=2;
d=(double)i;
d=(double)i;
printf("%f¥n",d);
printf("%f¥n",d);
}}
計算式中に複数の型が現れるときは、
優先順位に従って計算結果の型が決まる
int 型の変数 i の値を
double 型に変換したのち、
d に代入。
優先順位
int → (unsigned int →) long → (unsigned long →)
d=i としたときと同じ。
float → double → long double
気にしなくてもプログラムを書
くことができる場合も多い。
しかし、型変換を意識しない
といけない場合もある。
15/59
例:
int型 + long型 = long型
int型 + double型 = double型
演習:型変換(2)
演習:型変換(1)
実行し、何故そのような結果に
なるか、考えましょう
#include
#include <stdio.h>
<stdio.h>
main(){
main(){
printf("001->
printf("001-> %f¥n",5.0/4.0);
%f¥n",5.0/4.0);
printf("001->
printf("001-> %f¥n",5/4);
%f¥n",5/4);
printf("002->
printf("002-> %f¥n",5/4.0);
%f¥n",5/4.0);
printf("003->
printf("003-> %f¥n",(double)5/4);
%f¥n",(double)5/4);
printf("004->
printf("004-> %f¥n",(double)(5/4));
%f¥n",(double)(5/4));
}}
1 2
x
2
を計算しようと思い、次のプログラムを書いた。
#include<stdio.h>
#include<stdio.h>
#include<math.h>
#include<math.h>
main(){
main(){
double
double x=5,y;
x=5,y;
y=1/2*pow(x,2);
y=1/2*pow(x,2);
printf("%f¥n",y);
printf("%f¥n",y);
}}
実行して、結果を示しなさい。 もし、意図した値が出ていなかっ
たなら、出るように修正しなさい。
18/59
構造化プログラミング
全体の処理を、複数のサブルーチンの組み合わ
せとして記述するプログラミング手法。
構造化プログラミングでは、処理は上から順番に
実行されていく。
プログラムの流れは、基本的に次の3つしかない。
1. 順次:順番に実行していく
2. 分岐:条件に従って、行う処理内容を変える。
3. 反復:ある条件が満たされている間、繰り返す。
構造化プログラミングと
構成要素
19/59
C言語における分岐、反復
構造化プログラミングのメリット
全体の処理を、複数のサブルーチンの組み合わせと
して記述できるので、書く際にわかりやすい。
順次・分岐・反復しかないため、人間がプログラムの
処理の流れを追うときに、わかりやすい。
構造化プログラミングの場合の例
構造化プログラミング以外の場合の例
略
10
略
10 for
for i=0
i=0 to
to 10
10 上から下に
main(){
20
main(){
流れるとは
20 print
print ii
基本的に、
int
i;
30
int i;
限らない
上から下に
30 next
next ii
for(i=0;i<10;i++)
40
for(i=0;i<10;i++)
流れる
40 end
end
printf("%d¥n",i);
50
printf("%d¥n",i);
50 goto
goto 10
10
if(i==10)
60
if(i==10)
60 if
if i=10
i=10 then
then 70
70 else
else 40
40
printf("%d¥n",i);
70
print
printf("%d¥n",i);
70 print ii
}}
C言語におけて、分岐・反復を行うには、次のような
制御命令を使用する。
反復:
for
while
分岐:
if
switch
順次・分岐・反復の枠に入らない goto もあるが、
普通は使用しない。
for
演習:for
for(式1;式2;式3){
文
}
式1
式2
No
以下のように実行される
1. 式1を行う。
2. 式2を評価した結果が
真であるなら3に進む。
偽ならfor文を終了する。
3. 文を実行する。
4. 式3を行い、2に戻る。
Yes
文
式3
break があると、そこから for
の外までジャンプする。
01:
01:
02:
02:
03:
03:
04:
04:
05:
05:
06:
06:
07:
07:
08:
08:
09:
09:
10:
10:
11:
11:
#include<stdio.h>
#include<stdio.h>
int
int main(){
main(){
int
int i,x;
i,x;
}}
どのように処理が流れていくかを
表に書きましょう。
それぞれの行が実行されたとき、
変数の値がどうなるか、
表に書きましょう。
x=0;
x=0;
for(i=0;i<4;i++){
for(i=0;i<4;i++){
x=x+i;
x=x+i;
}}
printf("%d
printf("%d %d
%d ¥n",i,x);
¥n",i,x);
while
演習:while
while( 式 ){
文
}
No
式1
Yes
文
01:
01:
02:
02:
03:
03:
04:
04:
05:
05:
06:
06:
07:
07:
08:
08:
09:
09:
10:
10:
11:
11:
12:
12:
13:
13:
以下の様に実行される。
1. 式を評価する。結果が、
真なら2に進む。
偽ならwhileを終了する。
2. 文を実行する。
3. 1に戻る。
文中にbreak があると、
while を終了する。
if~else
if(式1){
文1
}else{
文2
}
式1
No
01:
01:
02:
02:
03:
03:
04:
04:
05:
05:
06:
06:
07:
07:
08:
08:
09:
09:
10:
10:
11:
11:
12:
12:
13:
13:
次のように実行される。
1. 式1を評価する。結果が、
真である場合、2に進む。
偽である場合、3に進む。
2. 文1を実行し、4に進む。
3. 文2を実行し、4に進む。
4. if文を終了する。
Yes
文2
else 以降は省略しても良い。
switch文
switch(整数式){
case ラベル1:
文2
default:
文3
}
#include<stdio.h>
#include<stdio.h>
int
int main(){
main(){
int
int i,t;
i,t;
}}
どのように処理が流れていくかを
表に書きましょう。
それぞれの行が実行されたとき、
変数の値がどうなるか、
表に書きましょう。
for(i=0;i<4;i++){
for(i=0;i<4;i++){
if(i%2){
if(i%2){
printf("%d
printf("%d is
is odd
odd ¥n",i);
¥n",i);
}else{
}else{
printf("%d
printf("%d is
is even
even ¥n",i);
¥n",i);
}}
}}
switch文の例
文1
case ラベル2 :
}}
i=1;
i=1;
x=0;
x=0;
while(i<5){
while(i<5){
x*=i;
x*=i;
i++;
i++;
}}
printf("%d
printf("%d %d
%d ¥n",i,x);
¥n",i,x);
演習:if
文1
どのように処理が流れていくかを
#include<stdio.h>
#include<stdio.h> 表に書きましょう。
それぞれの行が実行されたとき、
int
int main(){
main(){
変数の値がどうなるか、
int
int i,x;
i,x;
表に書きましょう。
複数の分岐を行う際に使用。
整数式を評価し、対応するラ
ベルまでジャンプします。
対応するラベルが無い場合、
defaultにジャンプします。
ラベルの数は任意です。
defaultは省略可能です。
途中で抜けるときは、berak
を用います。
29/59
#include<stdio.h> •
•
(略)
•
int t;
対応するラベルまでジャンプ
対応するラベルがないとdefaultにジャンプ
break で switch文の外に
scanf("%d",&t);
switch(t){
t=1のとき t=2のとき t=3のとき t=4のとき
case 1: 文1
case 2: 文2; break;
case 3: 文3
}
}
default:文3
30/59
演習:switch
#include<stdio.h>
#include<stdio.h>
int
int t;
t;
メモリとポインタの概念
scanf("%d",&t);
scanf("%d",&t);
switch(t){
switch(t){
case
case 1:
1: printf("April
printf("April ¥n");
¥n");
case
case 2:
2: printf("May
printf("May ¥n");
¥n");
break;
break;
case
case 3:
3: printf("June
printf("June ¥n");
¥n");
default:
default: printf("July
printf("July ¥n");
¥n");
}}
ビットとバイト
メモリとアドレス
計算機内部では、データは2進数で保存している。
計算機は、メモリにデータを蓄えている。
bit
1bit
0 もしくは 1 のどちらかを保存
byte
1bitが8つ集まっている。
1byte
byte が、メモリの基本単位として使用される。
メモリの概念図
メモリは、1byteを保存で
きる場所が大量にある。
0000
0001
0002
それぞれの場所には、
0003
アドレスがふられている。
0004
0005
0006
アドレスがふられている
C言語の変数とメモリ
アドレスの参照とは
C言語で用いる変数等も、実際の値はメモリ上にある。
メモリ上のどこに置くかとかは、OSやコンパイラが
適時やってくれる。
0000
0001
0002
0003
0004
これは此処
に入れるか
変数T
計算機
変数Tを
使用と・・・
人
C言語では、実際にどこにデータが保存されているの
か、プログラム中で参照できる。
0000
0001
0002
0003
0004
変数Tの
アドレスは?
計算機
変数T
0002です
人
アドレスの参照の方法
アドレスにある値の参照
変数の前に & をつけると、その値をどこに保存して
いるか(アドレス)を参照できる
例: #include
#include <stdio.h>
<stdio.h>
その場所に入っている値は何?
main(){
main(){
int
int i;
i;
}}
『どこに保存されているか』はわかる。
次にやりたいことは?
アドレスの前に * をつけると、そのアドレスに保存
している値を参照できる
pirntf("%u¥n",&i);
pirntf("%u¥n",&i);
更に、C言語では、アドレスを保存する型も存在する。
&i とすることで、i が保存されているアドレスを参照できる。
ポインタとアドレス
ポインタ
ポインタの宣言(1)
ポインタ → アドレスを保存している変数です。
このポインタを型として宣言することができます。
整数型や文字型と合わせて宣言されます。
『変数 poi はアドレスである』と宣言するのではない!。
『変数 poi は整数型の変数を保存しているアドレス』
『変数 poi は文字型の変数を保存しているアドレス』
のように、どの型を保存しているアドレスなのかを区別。
ポインタの宣言の仕方
例: #include
#include <stdio.h>
<stdio.h>
*poi_01は整数型である。
main(){
main(){
int
int i;
i;
int
int *poi_01;
*poi_01;
int
int arr[10];
arr[10];
}}
poi_01の部分が
整数型のデータを保存する
アドレスを保存するポインタ
となる。
宣言するときに * をつけると、
* の次の文字は、ポインタになる。
ポインタの宣言(2)
#include
#include <stdio.h>
<stdio.h>
main(){
main(){
int
int i;
i;
int
int *poi_01;
*poi_01;
int
int arr[10];
arr[10];
}}
整数型の変数 i を宣言
整数型の変数 *poi_01 を宣言
poi_01はアドレス
サイズ10の整数型の配列
arrは配列の最初の要素のアドレス
アドレスを参照するには
int i;
サンプルプログラム
&i
値を参照するには
i
int *poi_01; poi_01(または &*poi_01)
*pot_01
int arr[10];
arr[0]
arr
#include
#include <stdio.h>
<stdio.h>
int
int main(){
main(){
unsigned
unsigned int
int i=101;
i=101;
unsigned
unsigned int
int *poi_01;
*poi_01;
unsigned
unsigned int
int arr[10]={103,2,3,4,5,6,7,8,9,10};
arr[10]={103,2,3,4,5,6,7,8,9,10};
*poi_01=104;
*poi_01=104;
printf("%u¥n",i);
printf("%u¥n",i);
printf("%u¥n",&i);
printf("%u¥n",&i);
printf("%u¥n",*poi_01);
printf("%u¥n",*poi_01);
printf("%u¥n",poi_01);
printf("%u¥n",poi_01);
printf("%u¥n",arr);
printf("%u¥n",arr);
printf("%u¥n",&arr[0]);
printf("%u¥n",&arr[0]);
}}
来週以降にやること
関数と値渡し、アドレス渡し
スコープ
構造体
おわりに
43/59
© Copyright 2025 Paperzz