質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

8344閲覧

(char *)とは...

Green-Tea

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

2クリップ

投稿2016/01/27 14:54

編集2016/01/27 14:56

###(char *)の意味

www9.plala.or.jp/sgwr-t/lib/free.html
様のソースコードを読んでいたらむ??となったので質問させていただきました。

C

1str = (char *)malloc(100);

において(char *)とはどのような働きをしているのでしょうか?
推測では型変換の明示的な宣言なのかと考えておりますが調べてもぴったりくるものがないので質問させていただきました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

C 言語なんて 20 年以上書いていないんじゃないか、というおっさんの答えでアレですが。
malloc は引数で指定されたバイト数の領域を確保する命令で、無事領域が確保できたらその位置を特に型の決まっていないポインタ、すなわち、void * で返すわけですね。
確保できた領域は、なにがしかの値を入れて使うわけですが、その使うときの型を明示的に指定しているのが (char *) でやっているキャストですね。
例に挙げられたコード中の str は、名前からして文字列として使う char * 型の変数なのでしょうから、

c

1char *str; 2str = (char *)malloc(100); 3gets(str); /* とか strcpy(str, buffer); */

とかやって使うのでしょうね。
で、char 型なんですが、これは処理系によらず 1 バイトであることが保証されているので、(char *)malloc(100) で確保した領域は、文字列以外に 1 バイトデータを格納する配列として使うこともあるでしょう。

c

1int i; 2char *str; 3char *p; 4str = (char *)malloc(100); 5if (str != NULL) { 6 for (i = 0, p = str; i < 100; i++, p++) { 7 *p = char_array[i]; 8 ... 9 ... 10}

あんまりいい例じゃないですが、こんな感じで使うとか。pchar * なので、++ するごとに次の char の位置に進む、すなわち 1 バイトずつ進むと。

int 型なんかのサイズは処理系依存です。実際は 2 バイトかもしれないし 4 バイトかもしれない、と。なんで sizeof で型のサイズを調べてその分の領域を確保するってのがセオリーですよね。(型 *)malloc(sizeof(型)*数) というのはイディオムじゃないでしょうか。

c

1int i; 2int *buf; 3int *p; 4buf = (int *)malloc(sizeof(int) * 100); 5if (buf != NULL) { 6 for (i = 0, p = buf; i < 100; i++, p++) { 7 *p = int_array[i]; 8 ... 9 ... 10}

こんな感じで。p++ すると p は 2 バイトだか 4 バイトだかわかりませんが、ともかくその処理系での int のサイズ分だけ進んで、ちゃんと次の int 型変数の位置に行く、と。

こんな答えで疑問を解決するのに役立つでしょうか。


2016-01-30 13:10 追記

超久しぶりに、C 言語のプログラム書いてみました。スタック上の整数配列 numnlist に格納してある値を、int 型としてみたり、どういうバイト列なのかを (unsigned char 型で) 見たり、無理矢理倍精度整数と見なしてみたり、というのをやってみています。

c

1#include <stdio.h> 2void main() { 3 int numlist[] = { 4095, 1023, 9999, -23 }; 4 int *p4int; 5 unsigned char *p4char; 6 long *p4long; 7 int i, n; 8 9 printf("numlist のアドレス = %08x\n", numlist); 10 printf("numlist[0] のアドレス = %08x\n", &(numlist[0])); 11 printf("numlist[1] のアドレス = %08x\n", &(numlist[1])); 12 13 p4int = numlist; /* numlist は &(numlist[0]); に等しい */ 14 n = sizeof(numlist) / sizeof(int); 15 for (i = 0; i < n; i++, p4int++) { 16 printf("int[%d] = %d\n", i, *p4int); 17 } 18 19 p4char = (unsigned char *)numlist; 20 n = sizeof(numlist) / sizeof(unsigned char); 21 for (i = 0; i < n; i++, p4char++) { 22 printf("byte[%d] = 0x%02x\n", i, *p4char); 23 } 24 25 p4long = (long *)numlist; 26 n = sizeof(numlist) / sizeof(long); 27 for (i = 0; i < n; i++, p4long++) { 28 printf("long[%d] = %ld\n", i, *p4long); 29 } 30}

投稿2016/01/27 15:41

編集2016/01/30 04:17
unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/01/27 16:02

....つまり(型 *)でmallocで確保したメモリに意味というか、「お前はこの型だぞ。」って教えている感覚でいいんでしょうか。 またmalloc(*)において *にはバイトの大きさが入ることがやっとつながりました
Green-Tea

2016/01/27 16:04

細かく教えて下さったのでunauさんにベストアンサーを差し上げます。 回答ありがとうございました
unau

2016/01/28 01:01 編集

ちょっと気になったので補足を。 `(型 *)` でキャストするのは確保したメモリに意味を与えるんじゃなくて、`void *` 型で `malloc` からで帰ってきたアドレス値を変数に格納する際に、「私はちゃんと意図的に `char` 型のポインタ型に入れているんですよ」と明示的にコンパイラに教えている、という捉え方がいいんじゃないか、と思います。 `malloc` で取った領域自体に型はなく、たとえば、`int` 型の値を突っ込んでおいて、そのバイト値がどうなっているかを `char` 型で調べる、とかもできるわけですから。 ```c int i; int bytes = sizeof(int) * 2; char *p; int *array; array = (int *)malloc(bytes); array[0] = 100; array[1] = -100; for (p = (char *)array, i = 0; i < bytes; i++, p++) { /* *p で array の中のバイト値を一つ一つ覗いていく */ } ``` 繰り返しになりますが、意味を持たせているのは「確保した領域」ではなく、そこを指しているポインタです。同じ領域をそれぞれ別の意味を持った複数のポインタで指し示すことができるのですから。
Green-Tea

2016/01/30 02:23

おお!!つまりmalloc関数以外の時にも(型 *)はつかえ、かつmalloc関数によって得たメモリ領域はいつまでたっても本質的には(void *)であるということですか...!!
unau

2016/01/30 04:08

そうですね、malloc で取ったようなヒープ上の領域だけなく、スタック上の変数の領域も、アドレスを得てポインタでアクセスできますが、そのときも明示的に型を指定して使います。 コメント欄だと例を書いてもシンタックスハイライトされないみたいなので、回答として書いてみますね。
unau

2016/01/30 04:18

回答に追記してみました。
guest

0

こんにちは。

それはキャストです。

推測では型変換の明示的な宣言なのか

でだいたいあってますよ。

malloc()は、void*型の値を返却します。それって「ニュートラル」なポインタです。
それをchar型を指すポインタへ変換しています。

投稿2016/01/27 15:05

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/01/27 16:03

なるほど。メモリだけ確保しても使いずらいだけですもんね.... もう少し調べてみます。
guest

0

う~ん。

str = (char *)malloc(100);

昔、UNIXかHP-UXあたりで、キャスト(明示?)し忘れたら、
左右の型が違うとかのワーニング出た記憶がある。

投稿2016/09/26 08:54

Huyuto

総合スコア67

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

(char *)とはどのような働きをしているのでしょうか?

意味はありますが、働きはありません。
意味としては、左辺の型を明示して読み手に伝える意味です。
働きという意味では、mallocが返すのは void *型で、これは「どんなポインタ型変数にも代入できる型」なので、単に、str = malloc(100); と書いても全く同じです。そういう意味で働きはない。
ただし、コーディングルールで、「代入の時は両辺の型を合わせておく」ということがあるのなら必須です。

投稿2016/01/28 02:38

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/01/30 02:25

ひとに分かりやすくするためにあるんですか
otn

2016/01/30 08:38

> ひとに分かりやすくするためにあるんですか このケースに限って言えばそうですね。 int *の値をchar *にキャストするというようなケースでは、意味も働きもあります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問