自作関数の引数となっているポインタ変数宣言にconstをつけてみる その1


ソーラー「さきのエピソードではポインタ変数宣言に


const int *pta = &a;


のように


const


がついている場合


アドレス&aのメモリ


つまり


変数aのメモリに格納されている数値は変更されないけど


ポインタ変数ptaに格納されているアドレスは&aから変更できることが分かったね。


先程のプログラムをもう1度みてみよう」



#include<stdio.h>


int main(void)

{

int a = 3;

const int *pta = &a;


//ポインタ変数ptaに変数aのアドレス&aを代入しています


/*constを変数宣言の前に使用する場合は変数宣言は初期化されていないといけません 初期化せずにコンパイルするとエラー文が表示されますが

constをポインタ変数宣言の前に使用する場合はポインタ変数宣言は初期化されている必要はありません*/


printf("%p\n", pta);

printf("%d\n", *pta);


/*ポインタ変数ptaに間接参照演算子*を用いることにより

ポインタ変数ptaに格納されているアドレス&aのメモリに格納されている数値がどうなっているのかを確かめようとしています*/


int b=5;


pta=&b;


//ポインタ変数ptaに変数bのアドレス&bを代入します


printf("%p\n", pta);

printf("%d\n", *pta);


/*ポインタ変数ptaに間接参照演算子*を用いることにより

ポインタ変数ptaに格納されているアドレス&bのメモリに格納されている数値がどうなっているのかを確かめようとしています*/


return 0;

}


(EAZY IDECの場合)


コンパイル結果

0091FF54

3

0019FF4C

5


(Visual studioの場合)


ビルド実行結果

001BFED4

3

001BFEBC

5


ソーラー「ああ、麗しい


const int *pta = &a;


と記述されていると


*ptaに格納されている数値は変更することができるんだけど


変数aに格納されている数値は変更できないという話だったね


constが機能していないというわけではなかったね。」




ソーラー「ああ、麗しい」




アレサ「ジャムの製造にも成功しました。」


ソーラー「なにぃ


プログラムの技術習得よりも


お料理の技術習得の方がさきにすすんでいる・・・


ラッキ~~~


いやあ  最近  おいしいものばっかり食べさせてもらって


ありがたいな・・・」



アレサ「お喜びいただけてなによりです


プログラムの技術習得も


お料理の技術習得も


同じような


構造となっているため


習得するのに差を感じません


簡単な工程を繰り返しているだけですの」



ソーラー「




   🍓簡単な工程を繰り返しているだけ・・・か・・・🍓





いい言葉だね。


簡単な工程をくりかえすだけなら



だれでも技術習得は用意なはずだね」


ソーラー「おっと


今 

確か


ポインタ変数宣言にconstを使用した場合


変数aに格納されている数値は変更できなくなるけど


作製されるポインタ変数ptaに格納される値は


自由に変更できるという話だったね。


ならば


自作関数の引数となっているポインタ変数宣言


int *ptaにconstを使用したら


作製されるポインタ変数に格納される値は変更することができるのか


変更することができないのか


どうか


確かめてみよう


と思ったんだ。」


アレサ「まずは


自作関数の引数にポインタ変数宣言を用いた


プログラムを用意いたします」


ソーラー「いいねえ」


#include <stdio.h>


void function(int *ptx) {


printf("%d\n", *ptx);


return;


}


int main(void) {


int a=1;


function(&a);


return 0;


}


(EAZY IDECの場合)

コンパイル結果

1


(Visual studioの場合)

ビルド実行結果

1



アレサ「このプログラムでは


自作関数の引数となっているポインタ変数ptxに


アドレス&aをわたすことにより


*ptxはアドレス&aのメモリにアクセスすることができるようになり


*ptxはアドレス&aのメモリに格納されている数値データ1を表します。


ですので



function(&a);

自作関数の実行が行われると


printf("%d\n", *ptx);


が行われて


コンパイル結果に1


が表示されます」


ソーラー「ここで


printf("%d\n", *ptx);


が実行されて


コンパイル結果に


2が表示されるよう


プログラムに手を加えてみます。



#include <stdio.h>


void function(int *ptx) {


int b=2;


ptx=&b;


printf("%d\n", *ptx);


return;


}


int main(void) {


int a=1;


function(&a);


return 0;


}


(EAZY IDECの場合)

コンパイル結果

2


(Visual studioの場合)

ビルド実行結果

2


ソーラー


自作関数の定義が


void function(int *ptx) {


int b=2;


ptx=&b;


printf("%d\n", *ptx);


return;


}

になっていることにより


function(&a);



ポインタ変数ptaに格納されているアドレス&aを


ptx=&b;


により


&aから&bに変更することができます。


よって


printf("%d\n", *ptx);


のコンパイル結果を


アドレス&aのメモリに格納されている数値1から


アドレス&bのメモリに格納されている数値2に変更することができているね。」


アレサ「ポインタ変数ptxにアドレス&aを代入すると


*ptxはアドレス&aのメモリに


アクセスして


アドレス&aのメモリに格納されている数値を


表すようになるのがポイントですの。」


ソーラー「それで次は


このプログラムの


自作関数の引数となっているポインタ変数宣言


int *ptxに


constを使用すると


今、実行した


自作関数の引数となっているポインタ変数ptxに


constが使用されていない


プログラムと同じように


ポインタ変数ptxに格納されるアドレスが&aから&bに変更されるか


それとも


constが機能して


ポインタ変数ptxに


格納されるアドレスが&aから&bに変更されないのか


確かめてみたいというわけなんだ


ではさっそく自作関数の定義を


void function( int *ptx) {


int b=2;


ptx=&b;


printf("%d\n", *ptx);


return;


}


から


void function(const int *ptx) {


//🌞constを追加しました


int b=2;


ptx=&b;


printf("%d\n", *ptx);


return;


}


に変更して


プログラムを構成してみよう。


もし


constがポインタ変数ptxに作用しているなら


function(&a);



ポインタ変数ptxに&aが代入されたあとに


自作関数の定義の中の


int b=2;


ptx=&b;👈


👈の


ptx=&b;👈

命令文は実行されないので


コンパイルエラーがでるはずだよね。



#include <stdio.h>


void function(const int *ptx) {


int b=2;


ptx=&b;


printf("%d\n", *ptx);


return;


}


int main(void) {


int a=1;


function(&a);


return 0;


}


(EAZY IDECの場合)

コンパイル結果

2


(Visual studioの場合)

ビルド実行結果

2



ソーラー「コンパイルに成功している!



やはり 自作関数の引数となっている


ポインタ変数宣言int *ptxにconstをもちいても


ポインタ変数ptxに格納されるアドレスを&aから&bに変更できているね。


つまり


先程のエピソードでもみてきたように


const int *ptx


によって作成されるポインタ変数ptx



アドレス&aが代入された場合


constによって格納されている値が


変更されないようになっているのは


ポインタ変数ptaに格納されているアドレス&aではなく


変数aという名前の付いたメモリに格納されている数値1なんだ。


だから


今のプログラムのように


int b=2;

ptx=&b;



実行されて


*ptxに格納されている数値が


1から


2になることは可能なんだよね。


だって


constによって格納されている値が


変更されないようになっているのは


変数aという名前の付いたメモリに格納されている数値1だからね。


int b=2;

ptx=&b;



実行されて


*ptxに格納されている数値が


1から


2になっても


変数aという名前の付いたメモリに格納されている数値は


1のまま変更されないってわけだ。」














まだまだ  つづきますよ~😊


              solarplexussより

















ソーラー「ここで


コンパイル結果に2を表示させようとすると



自作関数の定義は



#include <stdio.h>


void function(int *ptx) {


*ptx=2;


printf("%d\n", *ptx);


return;


}


となります


プログラムを構成してみると


#include <stdio.h>


void function(int *ptx) {


*ptx=2;


printf("%d\n", *ptx);


return;


}


int main(void) {


int a=1;


function(&a);


return 0;


}


(EAZY IDECの場合)

コンパイル結果

2


(Visual studioの場合)

ビルド実行結果

2



ソーラー「このプログラムの場合では


function(&a);



ポインタ変数ptaに変数aのアドレス&aが代入されていますが











  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます