char**型のポインタ変数pを用いて動的にメモリを確保してみよう💖

char**型のポインタ変数pを用いて動的にメモリを確保してみよう💖

ソーラー「今日は


int型の変数のアドレスを格納することのできるポインタ変数のアドレスを格納することができるchar**型のポインタ変数


をもちいて動的にメモリを確保してみたいと思います。」



solarplexuss「


char**型のポインタ変数


をもちいて動的にメモリを確保する?


どこかで


動的にメモリを確保したことがあったような・・・」


ソーラー「以前のエピソードで


malloc関数を用いてメモリを


動的に確保したことがあります


まあ 次のプログラムをみ・て・よね😸。


#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


char *p ;


p= (char *)malloc(sizeof(char)*100);


if (p == NULL) {

printf("メモリは確保されませんでした。");

}


else {

printf("メモリは確保されました。");

  printf("そのメモリのアドレスは %pです。\n", p);

}


free(p);


return 0;

}


ビルド実行結果


メモリは確保されました 。

そのメモリのアドレスは00D94B40です。


ソーラー「思い出したかな~😊」


solarplexuss「あった、あった(´▽`*)」


アレサ「はい、思い出しましたの」


solarplexuss「


これはどのようなことを行っているプログラムだったっけ?」



ソーラー「よ~し、では


このプログラムの解説に取り掛かってみようかな


まず


#include <stdlib.h>


に注目だね。


malloc関数はヘッダファイル<stdlib.h>を


インクルードしないとつかえないんだ。



そして


char *p ;


p= (char *)malloc(sizeof(char)*100);


の意味だね。


p= (char *)malloc(sizeof(char)*100);



sizeof(char)*100は確保したいメモリのバイト数を表しています


char型は1バイトのデータ格納容量をもちます


ですので


それを100倍した


(char)かける100である


(char)*100は


100バイトのデータ格納容量を持つことになり


sizeof(char)*100 は100をあらわします。


malloc関数は


引数に確保したいメモリのバイト数が渡されると


100バイト分のメモリを確保することになります


例えば

00D94B40

00D94B41

00D94B42

00D94B43

00D94B44

00D94B45

00D94B46

00D94B47

00D94BA2

00D94BA3

のアドレス番号をもつ100バイト分のメモリが


malloc(sizeof(char)*100);


の実行により


確保されます。


そのとき


確保した100バイトのメモリの


先頭のアドレス


00D94B40をmalloc関数は戻り値として持つことになります



その戻り値となっているアドレスを格納するために


pのポインタ変数宣言


char *p ;


が行われているですね。」


アレサ「なつかしいです」


ソーラー「そうだね


ところで


ここで気になるのが


p= (char *)malloc(sizeof(char)*100);


という表現です


ポインタ変数pにアドレスを格納するなら


p= (char *)malloc(sizeof(char)*100);


でなく


p=malloc(sizeof(char)*100);


でもよさそうですよね。


どう思うかな。 みなさん」


アレサ「malloc(sizeof(char)*100)はアドレス00D94B40を戻り値として


もつですか・・・」


ソーラー「実は


malloc(sizeof(char)*100)はアドレス00D94B40を戻り値としてもつのですが


(char *)malloc(sizeof(char)*100)


のように


キャスト演算子()を用いて


キャラアスタリスク型char *に


malloc(sizeof(char)*100)を格納して



キャラアスタリスク型char *に


malloc(sizeof(char)*100)の戻り値である


アドレス00D94B40を


格納する必要があります


そうしなければ


キャラアスタリスク型char* 型のポインタ変数pに


p= (char *)malloc(sizeof(char)*100);


のように


アドレス00D94B40を渡すことはできないんです


ここがおもしろいところだよね。


アドレス00D94B40が


キャラアスタリスク型char *でメモリに格納されているのか?


イントアスタリスク型int *でメモリに格納されているのか?


ということをコンピュータに理解させるために


(char *)malloc(sizeof(char)*100);


のように


(char *)を用いる必要があるのですね


お話は飛ぶけど


イントアスタリスク型int *もアドレスを格納する働きがあります。」



🌞    🌞    🌞


このとき


キャラアスタリスク型char *にキャスト演算子()を用いて


アドレス00D94B40を格納することを


キャラアスタリスク型char *にアドレス00D94B40を



          🍋キャスト🍋


するといいます。


キャストとは英語で搭載するという意味です。


天国にいけるC言語入門


https://kakuyomu.jp/works/1177354054881541562/episodes/1177354054884520154


のエピソードでもキャスト演算子は登場しましたね。



#include <stdio.h>


int main(void){


float a;

a=1.5;


printf("あなたの預金額はただいま%d円です。\n",(int )(10000*a));

/*ここでキャスト演算子( )をもちいることにより実数値である(10000*a)をint型にキャストしています*/



return 0;


}


コンパイル結果


あなたの預金額はただいま15000円です。


(統合開発環境EAZY IDECの場合)


あなたの預金額はただいま15000円です。



ここでの注目ポイントは


         10000*aは実数値になるということです


   整数値と実数値を掛け合わせたものは実数値になるのでしたね


int型に格納されている数値とfloat型に格納されている数値を掛け合わせると


float型になるし


int型に格納されている数値とdouble型に格納されている数値を掛け合わせると


double型になるのでした




printf("あなたの預金額はただいま%d円です。\n",(int)(10000*a));


と記述していたのを


(int)を用いず


printf("あなたの預金額はただいま%d円です。\n",(10000*a));


と記述してしまうと



実数値である(10000*a)を



%d出力変換指定子を用いてprintf出力表示することになり


コンパイル結果


あなたの預金額はただいま15000円です。


を表示することはできません


そのことを示すプログラムは次のようになります

👇

#include <stdio.h>


int main(void) {


float a;

a = 1.5;


printf("あなたの預金額はただいま%d円です。\n", (10000 * a));

/*ここではキャスト演算子( )をもちいず実数値である(10000*a)をint型にキャストしていません*/



return 0;


}


コンパイル結果


あなたの預金額はただいま0円です。


(int)を用いて(10000*a)をint型に格納して


整数値15000にしておく必要があるのですね


このようにキャスト演算子()


は望みの型にデータを格納するために用いられます


               

                solarplexussより


めでたし  めでたし



solarplexuss「いやあ よかった、よかった


ところで


何のはなしだっだっけ?」



アレサ「solarplexussさん


int型の変数のアドレスを格納することのできるポインタ変数のアドレスを格納することができるchar**型のポインタ変数


をもちいて動的にメモリを確保してみたい


というお話でしたの(#^^#)」



solarplexuss「そうだった


今のプログラムでは


char*型のポインタ変数


をもちいて動的にメモリを確保した


めでたし


今度は


char**型のポインタ変数


をもちいて動的にメモリを確保したいということかな😊かな😊」


ソーラー「おめでとうございます


ビンポ~~ン


正解~です」


アレサ「冴え、冴えですね


solarplexussさん」


solarplexuss「わおう


char*型のポインタ変数pを用いて


動的にメモリを確保したいなら


char *p ;


p= (char *)malloc(sizeof(char)*100);


を実行すればいいんでしょう😊


じゃあ


char**型のポインタ変数pを用いて


動的にメモリを確保したいなら



char** p ;


p= (char *)malloc(sizeof(char)*100);


を実行すればいいんじゃないかな


そのプログラムは以下のようになるね

👇

#include <stdio.h>

#include <stdlib.h>//🌞malloc関数を使用するときはヘッダファイル<stdlib.h>をインクルードしてください


int main(void) {


char** p;


p = (char *)malloc(sizeof(char) * 100);


if (p == NULL) {

printf("メモリは確保されませんでした。");

}


else {

printf("メモリは確保されました。");

printf("そのメモリのアドレスは %pです。\n", p);

}


free(p);


return 0;

}


ビルド実行結果


エラー (アクティブ) E0513 型 "char *" の値を型 "char **" のエンティティに割り当てることはできません

エラー C2440 '=': 'char *' から 'char **' に変換できません。


solarplexuss「あれ?


なんで


ビルドエラーが表示される??」


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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る