---
title: cp-11. ポインタ
tags:  #プログラミング #c #ポインタ #メモリアドレス #配列 #関数へのポインタ渡し  
author: [kunihikokaneko](https://convert.docswell.com/user/6674398749)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/L71V2XZVJG.jpg?width=480
description: C プログラミング入門 （スライド資料とプログラム例）（Visual Studio 2019 を使用）（全１５回） https://www.kkaneko.jp/pro/adp/index.html  金子邦彦研究室ホームページ https://www.kkaneko.jp/index.html
published: February 21, 22
canonical: https://convert.docswell.com/s/6674398749/ZYMJEZ-2022-02-21-181331
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/L71V2XZVJG.jpg)

cp-11. ポインタ
（C プログラミング入門）
URL: https://www.kkaneko.jp/pro/adp/index.html
金子邦彦
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/G7WLRN93J2.jpg)

内容
例題１．変数のメモリアドレス表示
例題２．配列のメモリアドレス
例題３．２次元配列のメモリアドレス
メモリとメモリアドレス
例題４．棒グラフを表示する関数
関数への配列の受け渡し
例題５．２次元配列の受け渡し
関数への配列の受け渡し
例題６．局所変数と仮引数のメモリアドレス
例題７．関数へのポインタ渡し
関数へのポインタ渡しとポインタ変数
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4JZMR39G73.jpg)

目標
• データは，アドレス付けされて，メモリに入っ
ていることを理解する
• ポインタ変数を使い，関数との情報の受け渡し
ができるようになる
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/YE6NRXKQEV.jpg)

家と住所
福岡市東区
箱崎１丁目１番
Ａさんの家
福岡市東区
箱崎２丁目２番
Ｂさんの家
名前
家
住所
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/GE558XP2E4.jpg)

メモリアドレスとは
メモリ
age
１８
rate
107.75
変数名
変数の中身 メモリアドレス
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/972NKX61JR.jpg)

メモリアドレスとは
• すべてのデータには「メモリアドレス」が付けら
れている
変数の中身： 値
「１８」 「１０７．７５」 など
変数名：
プログラム内で使うための名前
「age」, 「rate」 など
メモリアドレス： 変数のそれぞれに付けられた「住
所」の
ようなもの
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/DJYPN894JM.jpg)

例題１．変数のメモリアドレス表示
• 次の３つの変数を使って，「底辺と高さを読み込
んで，面積を計算するプログラム」を作る．
底辺 teihen
浮動小数データ
高さ takasa
浮動小数データ
面積 menseki
浮動小数データ
• これら変数のメモリアドレスの表示も行う
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V7N5XQL6E8.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int main()
{
double teihen,takasa,menseki;
printf(&quot;teihen=&quot;);
scanf(&quot;%lf&quot;, &amp;teihen);
「&amp;」はメモリアドレス
printf(&quot;takasa=&quot;);
の取得
scanf(&quot;%lf&quot;, &amp;takasa);
menseki = teihen * takasa * 0.5;
printf(&quot;menseki = %f\n&quot;,menseki);
printf(&quot;address(teihen) = %p\n&quot;, &amp;teihen );
printf(&quot;address(takasa) = %p\n&quot;, &amp;takasa );
printf(&quot;address(menseki) = %p\n&quot;, &amp;menseki );
return 0;
}
「%p」はメモリアドレス
8
の表示


# Page. 9

![Page Image](https://bcdn.docswell.com/page/YJ9Y8D4R73.jpg)

変数のメモリアドレス表示
実行結果の例
teihen=3
takasa=4
表示された
メモリアドレス
menseki = 6.000000
address(teihen) = 0065FDF0
address(takasa) = 0065FDE8
address(menseki) = 0065FDE0
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/GJ8683QGED.jpg)

メモリアドレス
メモリ
menseki
6.000000
0065FDE0
takasa
4.000000
0065FDE8
teihen
3.000000
0065FDF0
変数名
メモリアドレス
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/LJL9RVXX7R.jpg)

メモリアドレスの取得と表示
printf(&quot;address(teihen) = %p\n&quot;, &amp;teihen );
メモリアドレスメモリアドレス
の表示
の取得
• 変数からメモリアドレスの取得
&amp;: メモリアドレスを取得するための演算子
変数名（など）の前に付ける
• メモリアドレスの表示のための書式
%p: メモリアドレスを表示せよという指示
printf 文などで使用
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/47MZRGL3JW.jpg)

例題２．配列のメモリアドレス
• 次の２つの配列を使って，ベクトル（1.9, 2.8, 3.7）
と，ベクトル（4.6, 5.5, 6.4）の内積を求めるプログ
ラムを作る．
ベクトル（1.9, 2.8, 3.7） u 要素数３の浮動小数の
配列
ベクトル（4.6, 5.5, 6.4） v 要素数３の浮動小数の
配列
• これら配列の要素について，メモリアドレスの表示
も行う
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/P7R6RZKRE9.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int main()
{
double u[]={1.9, 2.8, 3.7};
double v[]={4.6, 5.5, 6.4};
int i;
double ip;
「&amp;」はメモリアドレス
ip = 0;
の取得
for (i=0; i&lt;3; i++) {
ip = ip + u[i]*v[i];
}
printf(&quot;内積=%f\n&quot;, ip);
printf(&quot;address(u[0]) = %p\n&quot;, &amp;u[0]);
printf(&quot;address(u[1]) = %p\n&quot;, &amp;u[1]);
printf(&quot;address(u[2]) = %p\n&quot;, &amp;u[2]);
printf(&quot;address(v[0]) = %p\n&quot;, &amp;v[0]);
printf(&quot;address(v[1]) = %p\n&quot;, &amp;v[1]);
printf(&quot;address(v[2]) = %p\n&quot;, &amp;v[2]);
return 0;
}
「%p」はメモリアドレス
の表示
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/PJXMR9LYEX.jpg)

配列のメモリアドレス
実行結果の例
表示された
メモリアドレス
内積=47.820000
address(u[0]) = 0065FDE0
address(u[1]) = 0065FDE8
address(u[2]) = 0065FDF0
address(v[0]) = 0065FDC8
address(v[1]) = 0065FDD0
address(v[2]) = 0065FDD8
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/3JKGRPL47D.jpg)

メモリアドレス
メモリ
v[0]
v[1]
v[2]
u[0]
u[1]
u[2]
4.6
5.5
6.4
1.9
2.8
3.7
0065FDC8
0065FDD0
0065FDD8
0065FDE0
0065FDE8
0065FDF0
メモリアドレス
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/LE3N8X3DE5.jpg)

配列とメモリアドレス
配列 u
配列 v
（サイズは３）
（サイズは３）
０
０
１
１
２
２
添字
添字
２つの配列
メモリアドレス
v[0]
v[1]
v[2]
u[0]
u[1]
u[2]
4.6
5.5
6.4
1.9
2.8
3.7
0065FDC8
0065FDD0
0065FDD8
0065FDE0
0065FDE8
0065FDF0
メモリ内の配置
（配列の並びはそのままで
メモリに入る）
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/8EDWM2427G.jpg)

例題３．２次元配列のメモリアドレス
• 次の２つの配列を使って，２行３列の行列の和を
求めるようなプログラムを作る．
a ２行３列の行列 整数
b ２行３列の行列 整数
• 配列 a の要素について，メモリアドレスの表示も
行う
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/V7P9R1MLJ8.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int main()
{
int a[2][3]={{1,2,3},{4,5,6}};
int b[2][3]={{9,8,7},{6,5,4}};
int i;
int j;
「&amp;」はメモリアドレス
for (i=0; i&lt;2; i++) {
for (j=0; j&lt;3; j++) {
の取得
printf(&quot;%d, &quot;, a[i][j]+b[i][j]);
}
printf(&quot;\n&quot;);
}
printf(&quot;address(a[0][0]) = %p\n&quot;, &amp;a[0][0]);
printf(&quot;address(a[0][1]) = %p\n&quot;, &amp;a[0][1]);
printf(&quot;address(a[0][2]) = %p\n&quot;, &amp;a[0][2]);
printf(&quot;address(a[1][0]) = %p\n&quot;, &amp;a[1][0]);
printf(&quot;address(a[1][1]) = %p\n&quot;, &amp;a[1][1]);
printf(&quot;address(a[1][2]) = %p\n&quot;, &amp;a[1][2]);
return 0;
}
「%p」はメモリアドレス
の表示
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/2JVMRY96JQ.jpg)

２次元配列のメモリアドレス
実行結果の例
表示された
メモリアドレス
10, 10, 10,
10, 10, 10,
address(a[0][0]) = 0065FDE0
address(a[0][1]) = 0065FDE4
address(a[0][2]) = 0065FDE8
address(a[1][0]) = 0065FDEC
address(a[1][1]) = 0065FDF0
address(a[1][2]) = 0065FDF4
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/5EGGM9Z2EL.jpg)

メモリアドレス
メモリ
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
1
2
3
4
5
6
0065FDE0
0065FDE4
0065FDE8
0065FDEC
0065FDF0
0065FDF4
メモリアドレス
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/4JQXRWL9EP.jpg)

２次元配列とメモリアドレス
メモリアドレス
２次元配列 a
a[0][0]
a[1][0]
a[0][1]
a[1][1]
a[0][2]
a[0][0]
a[0][1]
a[0][2]
a[1][0]
a[1][1]
a[1][2]
1
2
3
4
5
6
0065FDE0
0065FDE4
0065FDE8
0065FDEC
0065FDF0
0065FDF4
a[1][2]
２次元配列
メモリ内の配置
（a[0][0] → a[0][1] → a[0][2] →
a[1][0] → a[1][1] → a[1][2]
21
の順で入る）


# Page. 22

![Page Image](https://bcdn.docswell.com/page/K7468K5RE1.jpg)

例題４．棒グラフを表示する関数
• 整数の配列から，その棒グラフを表示する
bar_graph 関数を作る．同時に， bar_graph
関数を呼び出すmain関数も作る
• 整数の配列及び配列のサイズをbar_graph関数に渡
すこと
• bar_graph関数の返り値はない（void とする）
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/LJ1V2XWVEG.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void bar( int len )
{
int i;
「整数の配列の先頭要素の
for (i=0; i&lt;len; i++) {
printf(&quot;*&quot;);
メモリアドレス」を受け取って，
}
配列 x として使う．
printf(&quot;\n&quot;);
return;
}
void bar_graph( int len, int x[] )
{
int i;
for (i=0; i&lt;len; i++) {
bar( x[i] );
}
return;
配列の先頭要素のメモリアドレスは
}
int main()
すでに受け取ったので，x[i] のように
{
int a[7]={6,4,7,1,5,3,2};書いて配列の要素を使える
bar_graph( 7, a );
return 0;
配列 a の先頭要素の
}
メモリアドレス（ &amp;a[0] の省略形）
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/GJWLRN63E2.jpg)

棒グラフを表示する関数
実行結果の例
*****
****
*******
*
*****
***
**
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/4EZMR3YGJ3.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
bar_graph( 7, a );
bar_graph 関数
void bar_graph( int len, int x[] )
関数呼び出し
bar( x[i] );
bar 関数
void bar( int len )
戻り
return;
戻り
return;
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/Y76NRXDQ7V.jpg)

関数への配列の受け渡し
• 呼び出し側
• 配列変数名を書いて，配列の先頭メモリアドレス
を，関数に渡す
例） bar_graph( 7, a );
• 関数側
配列 a の先頭要素のメモリアドレス
（ &amp;a[0] の省略形）
• 配列を受け取る（正確には，配列の先頭メモリア
ドレス）ことを宣言しておく
void bar_graph( int len, int x[] )
「整数の配列の先頭要素の
メモリアドレス」を受け取って，
配列 x として使う．
• 受け取った配列は，普通と同じに使える
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/G7558X3274.jpg)

配列とポインタ
プログラム例：bar_graph(7, a);
配列の先頭要素
a
a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
• プログラム中に配列名を単独（例えば「a」）で書
くと，配列の先頭要素のメモリアドレスという意味
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/9J2NKXZ1ER.jpg)

課題１．ベクトルの内積
• ２つの３次元ベクトルの内積を求める関数
product を作成しなさい．同時に， product 関
数を使う main 関数を作成し，正しく動作す
ることを確認すること．
• ２つの３次元ベクトルをproduct関数に渡すこと
• product関数の返り値として，求めた内積を返すこ
と
• 第５回の講義資料の「ベクトルの内積」の部分を
参考にして下さい
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/DEYPN8R4EM.jpg)

例題５． ２次元配列の受け渡し
• ２次元配列の先頭要素のメモリアドレスと，
配列の大きさから，配列の中身を表示する関
数を作る．
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/VJN5XQD678.jpg)

2次元配列の受け渡し
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void print_matrix( int *x, int n, int m ) {
int i;
「整数データのメモリアドレス」
int j;
を受け取って，x として使う．
for( i = 0; i &lt; n; i++ ) {
for( j = 0; j &lt; m; j++ ) {
printf( &quot;%d, &quot;, x[i*m+j] );
}
printf( &quot;\n&quot; );
}
return;
２次元配列 x の i 行 j 列目
}
int main()
{
int a[2][2] = {{1,2},{3,4}};
print_matrix( a, 2, 2 );
return 0;
30
配列 a の先頭要素のメモリアドレス
}


# Page. 31

![Page Image](https://bcdn.docswell.com/page/YE9Y8DGRJ3.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
print_matrix 関数
print_matrix( a, 2, 2 );
void print_matrix( int *x, int n, int m);
戻り
return;
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/GE8683VG7D.jpg)

２次元配列とポインタ
プログラム例： print_matrix( a, 2 );
２次元配列の先頭要素（つまり a[0][0]）
a
• ２次元配列の場合でも，プログラム中に配列名を単独で書
くと，配列の先頭要素のメモリアドレスという意味
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/LEL9RV5XJR.jpg)

x[i*n+j] の意味
２次元配列 a
a[0][0]
a[0][1]
配列の名前 a で
使用する場合の書き方
（main 関数内）
a[0][0]
a[0][1]
a[1][0]
a[1][1]
a[1][0]
配列の先頭アドレスが，
ポインタ変数 x に
入っている場合の書き方
1
2
3
4
x[ 0 * 2 + 0 ];
x[ 0 * 2 + 1 ];
x[ 1 * 2 + 0 ];
x[ 1 * 2 + 1 ];
a[1][1]
２次元配列
メモリ
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/4JMZRG33EW.jpg)

課題２．２つの行列の和
•
２つの行列の和を求める関数 add_matrix を
作成しなさい．同時に， add_matrix 関数を
使う main 関数を作成し，正しく動作するこ
とを確認すること．
•
add_matrix関数に渡されるのは次の通り
1. 和を求めるべき２つの行列
2. 行列の縦，横の大きさ
3. 求めた和を格納すべき行列
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/PJR6RZQR79.jpg)

例題６．局所変数と仮引数のメモリアドレス
• 整数から，その長さだけの棒を表示するbar 関数
と，bar関数を呼び出すmain関数を作る
• 局所変数と仮引数について，メモリアドレスを表
示することも行う
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/PEXMR95Y7X.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void bar( int len ) 仮引数（パラメータ）
{
int i; 局所変数
for (i=0; i&lt;len; i++) {
printf(&quot;*&quot;);
}
printf(&quot;\n&quot;);
printf(&quot;address(len) = %p\n&quot;, &amp;len);
printf(&quot;address(i) = %p\n&quot;, &amp;i);
return;
}
int main()
{
int len; 局所変数
printf( &quot;len=&quot; );
scanf( &quot;%d&quot;, &amp;len );
bar( len );
printf(&quot;address(len) = %p\n&quot;, &amp;len);
return 0;
}
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/3EKGRP64JD.jpg)

局所変数と仮引数のメモリアドレス
実行結果の例
len=10
**********
address(len) = 0065FDA4
address(i) = 0065FD98
address(len) = 0065FDF4
表示された
メモリアドレス
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/L73N8X6D75.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
bar( len );
bar 関数
void bar( int len )
戻り
return 0;
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/87DWM2V2JG.jpg)

メモリアドレス
メモリ
i
0
0065FD98
len
10
0065FDA4
bar 関数で使う部分
len
10
main 関数で使う部分
0065FDF4
メモリアドレス
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/VJP9R1VLE8.jpg)

関数呼び出しに伴うメモリ使用状況
の変化
メモリ
メモリ
bar 関数
で使う部分
main 関数
で使う部分
main 関数
で使う部分
メモリ使用状況
の変化
main 関数
関数呼び出し
bar( len );
bar 関数
戻り
return 0;
実行の
流れ
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/2EVMRYZ6EQ.jpg)

例題７．関数へのポインタ渡し
• 呼び出し側の局所変数を書き換えてしまうような
関数を作る
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/57GGM9427L.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void int_count(int *count_ptr) 仮引数
{
*count_ptr = *count_ptr + 1;
return;
}
int main()
{
int count = 0; 局所変数
while ( count &lt; 10 ) {
int_count(&amp;count);
}
printf( &quot;count=%d\n&quot;, count );
return 0;
}
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/4EQXRWG97P.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
int_count( &amp;count );
bar 関数
void int_count( int *count_ptr )
戻り
return;
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/KJ468K8R71.jpg)

仕事の依頼
○○の仕事を
頼む． 結果は，
その「箱」に入れ
てくれ！
○○の仕事を
頼む！
頼む人
頼む人
箱
頼まれる人
• 一方通行の場合
頼まれる人
• 返事を受け取り
たい場合
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/LE1V2X2V7G.jpg)

関数へのポインタ渡し
int_count(&amp;count)
count へのポインタ
(&amp;count で得られる）
変数 count
呼び出し側
• 関数 int_count の呼び出しで，&amp;count （変数
count へのポインタ）を渡す
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/GEWLRNR372.jpg)

関数にローカルなポインタ変数
int_count(int *count_ptr)
count へのポインタ
中身がコピーされる
変数 count
呼び出し側
count_ptr
count_ptr という名前の
付いたポインタ変数
（関数の中でのみ使用）
呼び出され側
• 関数に渡された &amp;count は，ポインタ変数 count_ptr
に格納される
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/47ZMR3RGE3.jpg)

ポインタ変数によるデータ操作
*count_ptr = *count_ptr +1;
count_ptr
変数 count
呼び出し側
関数の中から見ると，
*count_ptr はこれ
呼び出され側
• count_ptr が指している変数 count の値が１増える
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/YJ6NRXRQJV.jpg)

メモリ
メモリアドレス
が入る変数
count_ptr
int_count 関数で使う部分
整数データ
が入る変数
count
main 関数で使う部分
48


# Page. 49

![Page Image](https://bcdn.docswell.com/page/GJ558X82J4.jpg)

関数へのデータの受け渡し
関数に受
け渡され
るもの
ポインタ変数を
使わない場合
変数の「中身」
変数の値そのも
の
(call by valueという)
性質
一方通行（渡さ
れた変数の書き
換え不可能）
ポインタ変数を使
う場合
ポインタ変数の
「中身」
ある変数への ポイ
ンタ (call by reference
という)
渡された変数の書
き換え可能
49


# Page. 50

![Page Image](https://bcdn.docswell.com/page/LE3N8X81E5.jpg)

ポインタ変数
age
rate
変数の
名前
１８
age_ptr
107.75
rate_ptr
変数
ポインタ ポインタ
変数
変数の名前
50


# Page. 51

![Page Image](https://bcdn.docswell.com/page/8EDWM2MK7G.jpg)

ポインタ変数
• 変数： 数や文字を格納
（例） int age;
double rate;
• ポインタ変数： ポインタを格納
（例） int *count_ptr
• ポインタ変数も名前を持つ
（普通の変数と同じ）
51


# Page. 52

![Page Image](https://bcdn.docswell.com/page/V7P9R1R3J8.jpg)

ポインタ変数の宣言
• 変数名の前に ＊ を付ける
例）
int *age_ptr
52


# Page. 53

![Page Image](https://bcdn.docswell.com/page/2JVMRYRNJQ.jpg)

ポインタ変数＝＆変数
プログラム例： age_ptr = &amp;age;
age_ptr
変数 age
１８
• ポインタ変数 age_ptr に，変数 age へのポイ
ンタをセットする
53


# Page. 54

![Page Image](https://bcdn.docswell.com/page/5EGGM9M5EL.jpg)

変数＝＊ポインタ変数
プログラム例： x *
= age_ptr;
x
１８
age_ptr
age
１８
• 変数 x に，ポインタ変数 age が指している変
数の値をセットする
54


# Page. 55

![Page Image](https://bcdn.docswell.com/page/4JQXRWRLEP.jpg)

＊ポインタ変数＝「値」
プログラム例：
age_ptr
=
22;
*
age_ptr
age
２２
値が
セットされる
• ポインタ変数 age_ptr が指している変数 age
に，値「２２」をセットする
55


# Page. 56

![Page Image](https://bcdn.docswell.com/page/K7468K85E1.jpg)

ポインタ変数＝ポインタ変数
プログラム例： x_ptr = age_ptr;
age_ptr
x_ptr
age
18
• ポインタ変数 x_ptr に，age_ptr と同じポイ
ンタをセットする
56


# Page. 57

![Page Image](https://bcdn.docswell.com/page/LJ1V2X22EG.jpg)

ポインタを使ったプログラム例
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int main()
{
int age;
int *age_ptr;
age_ptr = &amp;age; ＆を使用
＊を使用
*age_ptr = 22;
printf( &quot;age = %d\n&quot;, age );
return 0;
}
• age_ptr は age を指しているから，
age は「２２」に変わる
57


# Page. 58

![Page Image](https://bcdn.docswell.com/page/GJWLRNR2E2.jpg)

ポインタを使ったプログラム例
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int main() {
int age;
int *age_ptr;
int *second_ptr;
＆を使用
age_ptr = &amp;age;
second_ptr = age_ptr;
＊を使用
*second_ptr = 22;
printf( &quot;age = %d\n&quot;, age );
return 0;
}
• いくつかのポインタ変数が，同じものを指し
ていてもかまわない
58


# Page. 59

![Page Image](https://bcdn.docswell.com/page/4EZMR3R4J3.jpg)

scanf に &amp; を付ける理由
• scanf では，変数に &amp; を付けることになって
いた
scanf(&quot;%lf&quot;, &amp;teihen);
書式
&amp; 読み込むべき変数名
• scanf は，データを読み込んだら，「メモリア
ドレス」を使って，読み込んだデータをメモ
リに置く
teihen
scanf(&quot;%lf&quot;,&amp;teihen);
浮動小数データを読み込み
59


# Page. 60

![Page Image](https://bcdn.docswell.com/page/Y76NRXRG7V.jpg)

課題３．スタック
• スタックの push 関数，pop 関数及び中身を表
示する関数を作成しなさい．同時に， これら
関数を使う main 関数を作成し，正しく動作
することを確認すること．但し，大域変数は
使わないこと
• main 関数の中で，配列及びスタックポインタの宣
言を行うこと
• push 関数，pop 関数内では，スタックポインタの
増減を正しく行うこと（ポインタ変数を使用する
こと）
60


# Page. 61

![Page Image](https://bcdn.docswell.com/page/G7558X8X74.jpg)

ptr++ の意味
int ary[7];
int *ptr;
ptr = &amp;a[0];
ポインタ変数 ptr に，配列
ary へのポインタをセット
ptr++;
ptr++;
printf ( “%d”, *ptr );
ptr を１つ動かす。
（a の次の要素 a[1] を指す)
ptr を１つ動かす。
（a の次の要素 a[2] を指す)


# Page. 62

![Page Image](https://bcdn.docswell.com/page/9J2NKXKQER.jpg)

２次元配列での ptr++ の意味
int a[1000][1000];
int *ptr;
ptr = &amp;a[99][0];
ポインタ変数 ptr に，配列
ary へのポインタをセット
ptr を１つ動かす。
ptr++;
（a の次の要素 a[99][1] を指す)
ptr を１つ動かす。
ptr++;
（a の次の要素 a[99][2] を指す)
printf ( “%d”, *ptr );
＊を使って、値を取り出す


# Page. 63

![Page Image](https://bcdn.docswell.com/page/DEYPN8NYEM.jpg)

文字列とポインタ
プログラム例： char string[6] = “March”;
char *ptr = &amp;string[0];
ptr
文字列 string への
ポインタがセットされる
string
M
a
r
c
h \0
文字列の終わり
を示す記号
ポインタ変数 ptr に，文字列 string へのポインタを
セットする (char* ptr = string; と書いてもよい）


# Page. 64

![Page Image](https://bcdn.docswell.com/page/VJN5XQXR78.jpg)

typedef
• typedef を使って，新しい型の名前を使えるよ
うになる
struct date {
int year;
int month;
int day
};
struct date a;
a.year = 2002;
a.month = 10;
a.day = 20;
typedef struct {
int year;
int month;
int day
} date;
同じ意味 date a;
a.year = 2002;
a.month = 10;
a.day = 20;


