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「あれ?
なんで
ビルドエラーが表示される??」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます