int (*i())[3];の宣言は、
変数iは、「int型の配列3個へのポインタを返す関数」ですが、
#include <stdio.h>
int array[3] = { 0, 1, 2 };
typedef int(*ap)[3];
ap i()
{
return array;
}
int main()
{
printf("%d\n", (*i())[0]);
printf("%d\n", (*i())[1]);
printf("%d\n", (*i())[2]);
}
の記述は、それぞれ0,1,2を表示してくれるようなのですが、
printf("%d\n", i()[0]);などの書き方は駄目なようなのですが、何故、この書き方ではだめなのでしょうか?
No.11
- 回答日時:
>int (*p)[3]のpの型は、
>int (*)[3]
>か
>int *[3]
>のどちらが正しいのでしょうか?
勿論宣言通りの int (*)[3] です。
ポインタだから、32ビットでコンパイルすれば常に4です。
sizeof(p) を調べるのが簡単です。
>sizeof()で調べると、
>sizeof(int (*)[3]) = 4
>sizeof(int *[3]) = 12
>となり、後の方が合っているように思うのですが?
int *[3] は intを指すポインタの配列(要素数=3)
なので sizeof(int *[3]) は sizeof(int *) * 3
という意味になります。
No.8
- 回答日時:
>arrayは先頭要素に対するポインタとも解釈できるので、
>その場合は、(int *)型と解釈できるのではないでしょうか?
同じじゃなくて、変換が必要になったときに変換されるという意味。
決して、配列とポインタは同じ型ではありません。
#最大の違いはサイズ
いつ変換がかかるのかを正確に学びましょう。
これは大鉄則なんで、いままでの誤った解釈はすっぱり忘れましょう。
No.7
- 回答日時:
int (*p)[3]: と宣言した場合
pは配列へのポインタ
p[0]は配列を返すから、配列はその先頭要素への「ポインタ」
に変換される。
つまり、p[0]はintじゃなくポインタ。簡単でしょ?
No.6
- 回答日時:
厳密にいえば, 単純に「arrayは先頭要素に対するポインタとも解釈できる」としてしまってはいけません. まず
配列名は「配列全体というオブジェクト」を表し, その型は「配列型」である
ということが前提で, そのうえで
特定の場合を除いて配列オブジェクトは先頭要素のアドレスに変換される
という規則を適用しなければなりません. 単に「array」とのみ書いた場合, 文脈がない以上「特定の場合」かどうかが判定できません. つまり, 下の変換をしていいかどうかわからないのです. よしんばポインタと解釈するとしても
「arrayの型は、(int *)になると思うのですが、
arrayの型を、(int [3])と解釈して」
は順序が逆です. 本来が int [3] で変換したあとが int *.
なお, 単項 & のオペランドになるときは「特定の場合」にあたる.
No.4
- 回答日時:
int x とすると、xのアドレス(intへのポインタ)を求めるには、 &x と &単項演算子を使います。
同様に、
array が int[3] なのだから、 arrayへのアドレスを求める & 演算子を使えば、int[3]へのポインタになり、キャストの必要はありません。
普通にC言語使っていたら、キャストが必要な場面なんてそうそうありません。
・int,double等の数値型の相互変換
・汎用ポインタとしての void *を元の型に戻す
くらいなものです。
それ以外で、キャストしないと警告やエラーが無くならないようなら、プログラムに間違いがあると思った方がよいです。
このプログラムも、
・ return array ; が間違っている
となりますが、他に
・(int *)[3] を戻り値に選んだことが間違っている
戻り値が int * なら、 return array ; で正しい
とも考えられます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 至急教えてください! プログラミングの問題です! お願いします! 出力2と全く同じ出力をするように、 2 2022/06/22 23:10
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
main(int argc,char **argv[])...
-
CImage GetBitsメソッドについて
-
戻り値で構造体を返すことは可...
-
Run-Time Check Failure #3とい...
-
C言語を勉強しています。
-
ポインタについて
-
NULLポインタが0でない処理系と...
-
関数宣言時の引数の*&はどうい...
-
変数
-
Cで作成したDLL関数をVBから呼...
-
C言語の初心者です。
-
fopne で失敗する原因
-
配列とポインタの違いについて
-
構造体のメンバーのメモリ確保
-
#define NULL ((void *)0) の弊害
-
関数へのポインタ渡し
-
関数の引数をvoid*でキャストする
-
C言語について教えてください。
-
C言語次のステップ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
init関数の意味
-
C言語のポインタに直接アドレス...
-
fopne で失敗する原因
-
Run-Time Check Failure #3とい...
-
C言語の関数と配列に関する質問
-
LPSTR型の初期化について
-
戻り値で構造体を返すことは可...
-
参照型で受け取った引数をポイ...
-
構造体とfscanf
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
Cで作成したDLL関数をVBから呼...
-
C言語でのconstを返す関数
-
main(int argc,char **argv[])...
-
DLL<->VB間での受け渡し(文字...
-
PASCALとFARの意味
-
エラーの意味
-
ハンドルはポインタか
-
TCHAR文字列内の検索について
おすすめ情報
ワーニングは出ています。
おっしゃるようにここは、
return array ではなくて
return (int (*)[3])array;
と書いて、関数i()の型であるapに合わせた方がいいですね。
配列の方を(int(*)[3])でキャストした配列へのポインタを返す方法もありますが、結局は
キャストはしてしまいます。
どんな方法があるのでしょうか?ご参考までに御教示ください。
ちょっとこんがらがって分からなくなりました。
通常、
int array[3];
と宣言した場合、
arrayの型は、(int *)になると思うのですが、
arrayの型を、(int [3])と解釈して、それへのポインタとして、(int (*))[3]が使えるということなのでしょうか?
arrayは先頭要素に対するポインタとも解釈できるので、
その場合は、(int *)型と解釈できるのではないでしょうか?
2つの解釈が可能。
int (*p)[3]のpの型は、
int (*)[3]
か
int *[3]
のどちらが正しいのでしょうか?
sizeof()で調べると、
sizeof(int (*)[3]) = 4
sizeof(int *[3]) = 12
となり、後の方が合っているように思うのですが?
pの型は「要素数3個のint型配列」になるので、その大きさは12バイトになると思うのですが。
sizeof()の使い方とか間違っています?