C言語関係掲示板

過去ログ

No.1191 ポインタのいろいろな宣言について

[戻る] [ホームページ]
No.15557

ポインタのいろいろな宣言について
投稿者---タニ(2004/07/15 20:56:12)


はじめまして、タニといいます。

C言語を勉強しているのですが、やはりポインタの部分は
難しいですね。

ポインタというのは、いろいろな宣言方法があるのですが
今まで学習してきた中で、わからないので無視してきた物が
ありましたが、わからないではすまないので誰かわかる方い
らっしゃいましたら解説願います。

int (*p)[]; int型配列を指し示すポインタ変数
char (*p) []; char型の配列へのポインタ変数の宣言

まず、これなんですが、具体的にはどういう意味になりますか?

次が全く意味不明です。
buf[2]=(int)((void *)sub_proc);
次も意味不明
void (*p)(void)=(void *)testcode;

voidに型変換しているみたいだけどありえるのかな?

誰かご指導いただける方いませんか?



No.15559

Re:ポインタのいろいろな宣言について
投稿者---シャノン(2004/07/15 21:26:00)


>int (*p)[]; int型配列を指し示すポインタ変数
>char (*p)[]; char型の配列へのポインタ変数の宣言

int a[10] の先頭要素のポインタは a、あるいは &a[0] ですが、
間違えて &a とかやると、そういうポインタが取れます。
何に使うのかはわかりません。

>次が全く意味不明です。
>buf[2]=(int)((void *)sub_proc);

void * にキャストしたものを int にしてる、そのまんまですね。
名前からして sub_proc は何らかの関数でしょうか。
関数のポインタを int に直接変換できないのかな?
ウチではできましたが。

>次も意味不明
>void (*p)(void)=(void *)testcode;
>voidに型変換しているみたいだけどありえるのかな?

これは、引数、戻り値ともに持たない
void func( void )
こんな「関数へのポインタ」に変換してます。変数名が p 。


No.15560

Re:ポインタのいろいろな宣言について
投稿者---NykR(2004/07/15 22:16:33)


>int (*p)[]; int型配列を指し示すポインタ変数

微妙に違います。pは、intの配列へのポインタ型を持つ変数です。
具体的にオブジェクトを指し示したり参照したりするのは左辺値であって、ポインタではありません。
“左辺値を作り出してオブジェクトを参照する”ための値がポインタです。
その値を格納するオブジェクト(ここではp)もポインタといいますが。

# pは“intの配列へのポインタ”を指し示す左辺値です
# *pは“intの配列”を指し示す左辺値になります。
# ただし不完全型なので*pという演算はまだできませんが。
# 関数へのポインタはここでは取り敢えず無視。


>char (*p) []; char型の配列へのポインタ変数の宣言

こっちは正しいですね。

例えば、配列の配列(多次元配列といいます)
char hoge[8][32];

という宣言をした場合、この配列の先頭要素の型は char[32]型になります。
そうすると先頭要素へのポインタは、char(*)[32]型ということになります。
配列は、式の中では少数の例外を除いて先頭要素へのポインタに変換されますから、

char (*p)[32] = hoge;

と初期化すれば、pに対してポインタ演算と間接参照を行うことによってhogeの各要素にアクセスできるようになります。
hogeの要素は要素数32の配列です。


>buf[2]=(int)((void *)sub_proc);

void*型(void型ではなく)にキャストしたあとさらにintにキャスト


>void (*p)(void)=(void *)testcode;

引数をとらない、返り値なしの関数へのポインタを、void*型にキャストした値で初期化。
規格ではこういう初期化は認められていません。


>voidに型変換しているみたいだけどありえるのかな?

voidへの型変換はしょっちゅう起こっています。
何らかの値を返す式の値を参照しなかった場合、その式はvoidに(暗黙に)変換されます。
警告レベルの高いコンパイラや、lintなどでは、値を返す式の値を参照しなかった場合は、
voidに明示的にキャストしないと警告を出すことがあります。

(void)printf("Hello, World\n");

というような。
つまり、void型は値を参照しない場合に使う型です。

# ただし、ここではvoidに型変換しているのは3つ目だけで、これは暗黙に
# (void)(buf[2]=(int)((void *)sub_proc));
# ということをやっているわけです。


No.15563

ありがとうございました
投稿者---タニ(2004/07/15 23:03:04)


タニです。

シャノンさん、NykRさん

お答えいただき、ありがとうございました。

三つともバッチリわかりました。