例えば、
問題② 次の計算をしなさい。
80円のリンゴ5個と90円のリンゴ2個と60円の柿6個と70円の梨3個を買いました。
と言う問題で
80円のリンゴ 5個
(80円のリンゴ を x とおく )
x = 5 (変数 x 整数型 int型 に 5 を代入)
・・・ ここまでは 私たちが判る話 ここから先は コンピュータの話 ・・・
変数 x は int型で 4バイト 0x0250 ~ 0x0253 番地のメモリに 5 収納します。
メモリの話をしますと、全てのメモリには番号が振られています。
番地それぞれに 16進数 で 00 ~ FF (2進数だと 0000 0000 ~ 1111 1111 )が入っています。
この値がコンピュータでは、プログラムや数値や文字になります。
1番地 = 1バイト で割り付けられます
全ての変数には、置かれるメモリ上の位置(番地)があり、それをアドレスと呼びます。その変数のアドレスを表す型がポインタ型と呼ばれています。
変数には、変数名、型、データ(文字、数値)、アドレスで構成されています。
-
- int *b;
ポインタの宣言
変数のアドレス(番地)を収納する変数をポインタと言います。 - b= &a;
&a は 変数a のアドレス になります。
ポインタ b に 変数a のアドレス を収納します。
- int *b;
《 test038.c 》
#include<stdio.h>
int main(){
int a=5;
int *b;
printf ("① a=%x a=%d \n",&a,a ) ;
a=2;
printf ("② a=%x a=%d \n",&a,a ) ;
b=&a;
printf ("③ a=%x b=%x \n",&a,b ) ;
*b=100;
printf ("④ a=%x b=%d \n",&a,*b ) ;
a=*b;
printf ("⑤ a=%d b=%x \n",a,b ) ;
}
実行するたびに変数のアドレスは変わりますが、実行されている期間は変更されません。
変数のポインタと同じように配列のポインタにもあります。配列の場合は最初の要素をポインタとしますが、配列の場合はポインタは変化します。
例えば、
ポインタ変数 P
まず、ポインタはA[0]になります。
P = P+1;
だと、1移動してポインタはA[1]になります。
P = P+2;
だと、2移動してポインタはA[3]になります。
アドレスは int の場合、4ビットずつになります。
A[0] のアドレスは 0番地
A[1] のアドレスは 4番地 になります。
#include <stdio.h>
int main(){
int A[] = { 5, 10, 15, 20,25,30 };
int *P ,i;
P = A;
printf("%d %d \n", *P, A[0]);
printf("\n");
for(i=0;i<5;i++){
printf("%d %X %2d %2d \n",i,P,*P,*P+2);
P += 1;}
printf("\n");
printf("%d %X %2d %2d \n",i,P,*P,*P+2);
P =P - 5;
printf("\n");
printf("%d %X %2d %2d \n",i,P,*P,*P+2);
}
8 ~ 10行 A[0] ~ A[4] の表示
10行 最後に 1 を加算されているので
12行 A[5] の表示になります。
13行 ポインタ値 に ー5 減算すると
15行 A[0] の表示になります。
変数、配列の要素ごとにポインタ(アドレス)がありますが、複数の型・変数から構成されている構造体は1つのポインタしかなく、構造体のメンバそれぞれには対応していません。
《 test040.c 》
#include <stdio.h>
struct list {
int no;
int money;
char goods[10];
};
int main(){
struct list com001 = {1,80,"Apple"};
struct list *p;
p=&com001;
printf ("%d %d %s \n",com001.no, com001.money, com001.goods);
printf ("%d %d %s \n",(*p).no, (*p).money, (*p).goods);
printf ("%d %d %s \n",p->no, p->money, p->goods);
printf ("%x \n",p);
}
結果
冒頭でも説明した通りアドレスは構造体に対応しています。
今まで、配列と構造体の知識があられば、簡単に対応できます。
アドレスの表し方
変数には、変数名、型、データ(文字、数値)、アドレスで構成されています。
-
-
-
- int *b;
ポインタの宣言
変数のアドレス(番地)を収納する変数をポインタと言います。
- b= &a;
&a は 変数a のアドレス になります。
ポインタ b に 変数a のアドレス を収納します。
- int *b;
-
-
《 test041.c 》
#include <stdio.h>
struct list {
int no;
int money;
char goods[10];
} ;
int main(){
struct list com[3] = {
{1, 90, "Apple"},
{2, 80, "banana"},
{3, 50, "orange"}
};;
int a ;
struct list *p;
p=com;
printf ("①\n");
for(a=0;a<3;a++)
printf ("%d %d %s \n", com[a].no, com[a].money, com[a].goods);
printf ("②\n");
for(a=0;a<3;a++) {
printf ("%d %d %s \n",(*p).no, (*p).money,(*p).goods);
++p;
}
p=p-3;
printf ("③\n");
for(a=0;a<3;a++) {
printf ("%d %d %s \n",p->no, p->money,p->goods);
++p;
}
}
実行するたびに変数のアドレスは変わりますが、実行されている期間は変更されません。