2 つの質問があります。
4 ビット システムでは、ポインターは 4 バイトであるというのは正しいですか?
「参照渡し」と「ポインタ渡し」は同じもので、言葉遣いが違うだけですか?
2 つの質問があります。
4 ビット システムでは、ポインターは 4 バイトであるというのは正しいですか?
「参照渡し」と「ポインタ渡し」は同じもので、言葉遣いが違うだけですか?
4 ビット システムではポインタ サイズは 4 です。
システムのバイト数が 1 ビットの場合、それは確実です。(しかし、C はとにかくバイトが 8 ビットより短いプラットフォームをサポートしていません。)
「参照渡し」と「ポインタ渡し」は同じものですが、言葉遣いが異なりますか?
いいえ。Pass-by-pointer は、参照渡しをエミュレートするための C のアプローチです。コンセプトが違います。
ポインタのサイズは、CPUのネイティブワードサイズと必ずしも相関していません。たとえば、元のMacintoshは、アドレスラインが24行しかない32ビットプロセッサ(Motorola 68000)で実行されていたため、ポインタは24ビットに制限されていました。ポインタ値は32ビットワードで格納されましたが、上位8ビットは使用されませんでした。一部の進取的なプログラマーは、これらの上位8ビットを使用して、ポインターを使用して他のデータを格納しました。これは、32のアドレス行を持つ68020が出たときに胸焼けを引き起こしました。そのコードを「32ビットクリーン」になるように書き直すのに少し時間がかかりました。
異なるタイプへのポインタは同じサイズである必要はないことにも注意してください。
実際には、最新のデスクトップシステム(読み取り:x86)では、すべてのポインタータイプは32ビット幅または64ビット幅のいずれかになります。しかし、それがすべてのアーキテクチャに当てはまるとは限りません。
「参照渡し」と「ポインタ渡し」については、いいえ、同じ概念の単なる異なる表現ではありません。
参照渡しシステムでは、関数定義の仮パラメーターと関数呼び出しの実パラメーターが同じメモリーを指定します(または、少なくとも一方への変更が他方に反映されます)。昔ながらのFortranコードを見てみましょう。
C234567890
PROGRAM CALLSW
INTEGER M, N
M = 1
N = 2
WRITE(*,*) M, N
CALL ISWAP(M, N)
WRITE(*,*) M, N
STOP
END
C234567890
SUBROUTINE ISWAP(A, B)
INTEGER A, B
INTEGER TMP
TMP = A
A = B
B = TMP
RETURN
END
の仮パラメータA
は、メインプログラムISWAP
と同じメモリ内のオブジェクトを指定するため、に書き込むと、の値が変更されます。あなたはへのポインタ(またはそれと両方が同じオブジェクトへのポインタである)と考えることができますが、言語はそのポインタ性をプログラマーから隠します。 M
A
M
A
M
A
M
Cはすべてを値で渡します; 仮パラメータと実際のパラメータは常にメモリ内の異なるオブジェクトを指定するため、一方に書き込んでも他方には影響しません。サブルーチン内のオブジェクトを変更する場合は、演算子を使用してそのアドレスを明示的に渡し、&
次に演算子を使用してサブルーチン内でオブジェクトを逆参照する必要があり*
ます。
void iswap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main(void)
{
int m, n;
m = 1;
n = 2;
printf("m = %d, n = %d\n", m, n);
iswap(&x, &y);
printf("m = %d, n = %d\n", m, n);
return 0;
}
m
とn
を渡す代わりに、2つのオブジェクトへのポインタである式とiswap
の結果を渡します。同様に、関数では、またはに書き込みません。式との結果に書き込みます。 そして、doと。のように、メモリ内の2つの完全に異なるオブジェクトを参照します。に書き込むことはまったく影響しません。 &m
&n
iswap
a
b
*a
*b
a
m
b
n
a
m
C でのパラメーターの受け渡しに関して、ウィキペディアの C に関するエントリには次のように記載されています。
関数パラメーターは常に値渡しされます。参照渡しは、ポインター値を明示的に渡すことによって C でシミュレートされます。