構造変数と比較した構造ポインターの利点は何ですか。また、特に関数パラメーターとして使用する場合に、多くの場合構造ポインターを使用する理由(さらに理解する必要があります)

タンハオチャンC言語第3版

関数パラメーターとしての構造ポインター変数

ANSI C規格では、構造変数は全体的な送信の関数パラメーターとして許可されていますしかし、この種の送信では、すべてのメンバーを1つずつ送信する必要があります特に、メンバーがアレイの場合、送信に多くの時間とスペースがかかり、プログラムの効率が大幅に低下します。したがって、最良の方法は、ポインターを使用することです。つまり、送信用の関数パラメーターとしてポインター変数を使用します。このとき、実際のパラメータから正式なパラメータにアドレスのみが渡されるため、時間とスペースのオーバーヘッドが削減されます。

 

アレイとは異なります

関数パラメーターとしての配列

配列は、データ送信の関数パラメーターとして使用できますアレイは、関数のパラメータとして使用されている二つの形式一方、実際のパラメータとして使用する配列要素(添字変数)であり他方は、関数パラメータと実際のパラメータとして配列名を使用することです

関数パラメーターとしての配列名

関数パラメーターとして配列名を使用することと、実際のパラメーターとして配列要素を使用することには、いくつかの違いがあります。

配列要素を実際のパラメーターとして使用する場合、配列タイプが関数の仮パラメーター変数のタイプと一致している限り、添え字変数として使用される配列要素のタイプも関数の仮パラメーター変数のタイプと一致します。したがって、関数の正式なパラメータも添え字変数である必要はありません。つまり、配列要素の処理は通常の変数として扱われます。配列名を関数パラメーターとして使用する場合、正式なパラメーターと対応する実際のパラメーターは同じタイプの配列である必要があり、明確な配列の説明が必要です。正式なパラメータと実際のパラメータに一貫性がない場合、エラーが発生します。

通常の変数または添え字変数が関数パラメーターとして使用される場合、正式なパラメーター変数と実際のパラメーター変数は、コンパイラシステムによって割り当てられる2つの異なるメモリユニットです関数が呼び出されたときに発生する値の転送は、実際のパラメーター変数の値を正式なパラメーター変数に割り当てることです。配列名が関数パラメーターとして使用される場合、それは値の転送ではありません。つまり、実パラメーターグループの各要素の値は、形状パラメーターグループの各要素に割り当てられませんので、それは実際のパラメータ配列を存在しない場合コンパイラシステムは、メモリサイズパラメータを割り当てるように設定されていませんでは、データ送信はどのように実現されますか?紹介したように、アレイ名はアレイの最初のアドレスです。したがって、配列名を関数パラメータとして使用する場合、送信はアドレス送信のみになります。つまり、実際のパラメータグループの最初のアドレスが形状パラメータグループ名に割り当てられます。形状パラメータグループ名が最初のアドレスを取得した後は、実際の配列を持つことと同じです。実際、形状パラメータグループと実パラメータグループは同じ配列であり、メモリ空間を共有します。

 

上の図は、この状況を示しています。この図では、aを実際のパラメーターグループとし、タイプは整数です。2000から始まるメモリ領域を占有します。bは形状パラメータグループの名前です。関数呼び出しが発生すると、アドレス送信が実行され、実パラメータグループaの最初のアドレスがシェイプパラメータグループ名bに送信されるため、bもアドレス2000を取得します。したがって、2つのアレイaとbは、最初のアドレスが2000の連続メモリユニットを共同で占有します。この図から、aとbの同じ添え字を持つ要素が、実際には同じ2つのメモリユニットを占有していることもわかります(整数配列の各要素は2バイトを占有します)。たとえば、a [0]とb [0]はどちらも2000ユニットと2001ユニットを占有しますが、もちろんa [0]はb [0]と同じです。類推により、a [i]はb [i]に等しい。

 

 

1.構造を使用して操作を実行する場合、たとえば、関数パラメーターとして、構造全体をコピーする必要があります(構造に含まれるバイト数、コピーする必要のあるバイト数)。
ポインタを使用するとはるかに便利で、コピーする必要があるのは4バイト(ポインタの長さ)だけです。パフォーマンスを節約

https://zhidao.baidu.com/question/2118370445891739467.html

2.(1)構造baiポインターが関数パラメーターとして使用される場合、呼び出し中に渡されるduは、構造変数(つまり、構造変数のアドレス)へのポインターです。構造変数が関数パラメーターとして使用される場合、呼び出し中に渡される構造変数自体。

(2)次のコードは呼び出し時の違いを示しています

#include <stdio.h>

/ *構造タイプポイントを定義します* /

typedef struct {

int x;

int y;

}ポイント;    

void fun1(ポイントポイント){

point.x + = 10;

point.y + = 10;

}

void fun2(Point pPoint){

pPoint-> x + = 10;

pPoint-> y + = 10;

}

void main()

{{

ポイントp;

px = 100;

py = 200;

/ * fun1を呼び出す* /

fun1(p);

printf( "x =%d、y =%d \"、px、py);

/ * fun2を呼び出します:pのアドレスをパラメーターとして取ります* /

fun2(&p);

printf( "x =%d、y =%d \"、px、py);

}

プログラムの出力は次のとおりです。

x = 100、y = 200

x = 110、y = 210

(3)上記のプログラムを実行した結果を見ると、fun1関数を実行した後、pは変化していませんが、fun2を呼び出した後、pは変化しています。これは、fun1が呼び出されると、渡されたパラメーターpが呼び出しスタックにコピーされ、fun1の操作が元の変数(メインのp)ではなくスタック内の変数であるためです。一方、fun2が呼び出されると、 pの着信アドレスfun2は、アドレスを介してmainの変数pを変更します。これは、構造ポインタと関数パラメータとして使用される構造変数の最大の違いです。

構造Aは、そのポインタがパラメータとして関数funcに渡されると、構造の値をfuncでポインタを介して変更できます。関数が戻った後、構造の値が変更されますが、構造変数がパラメータとして渡されると、関数がfuncの場合、func関数で変更されたとしても、関数が戻ったとき、変更は彼のコピーにすぎないため、構造自体は変更されません。

https://zhidao.baidu.com/question/594984205.html?qbl=relate_question_6&word=%BD%E1%B9%B9%CC%E5%D6%B8%D5%EB%BA%C3%B4%A6

おすすめ

転載: blog.csdn.net/qq_25814297/article/details/109194036