C中の関数のパラメータの少しの理解について

3390 ワード

一般的にc伝値は伝値と伝ポインタに分けられ、Javaにはポインタがないため伝値しかないが、Java伝値は単純変数伝値と参照型変数伝値に分けられ、本質的には両者に違いはない.
次に、パラメータ伝達時の元の変数への影響を主に説明します.
最初に単一チェーンテーブルの作成を練習するときに、次のような書き方があります.
void Creat_link_list(int n,struct node *head){
   
}

nは単一チェーンテーブルノードの個数であり、headはnullに初期化され、この関数を呼び出すと、遍歴、ソートなどのheadに直接様々な操作を行う人がいる可能性があります.しかし、headはnullのままであり、関数内の1列の操作はheadコピーの操作にすぎず、関数呼び出しが終了すると、このコピーはシステムによって解放されます.これには一般的に2つの変更があります.
(1):
struct node *Creat_link_list(int n,struct node *head){
   ..........
   ..........
   return head;
}

関数のheadを直接返すことができます.これは非常に重要な方法です.特に再帰コードでは、この書き方が一般的です(2):
void Creat_link_list(int n,struct node * &head){
   
}

引用伝参を採用し、c++に採用されている伝参方式で、形参と実参はメモリユニットを共用し、形参を操作し、実参も自然に影響を受け、一般的にはサボる方法としてもよく使われている(o(′▽`)o).
次に、厳書の二叉ソートツリーの削除操作を見てみましょう.
特に削除された関健操作:
void Delete(BiNode *&p){
  if(p->rchild==NULL){
   struct BiNode *q;
   q=p;
   p=p->lchild;
   free(q);
  }
  else if(p->lchild==NULL)
  {
   struct BiNode *q;
   q=p;
   p=p->rchild;
   free(q);
  }
  else{
  struct BiNode *q,*s;
  q=p;
  s=p->lchild;
  while(s->rchild){
   q=s;
   s=s->rchild;
  }
  p->data=s->data;
  if(q!=p)
  q->rchild=s->lchild;
  else
  q->lchild=s->lchild;
  free(s);
  }
}

コアコードを削除するには
   q=p;
   p=p->rchild;
   free(q);

これは、通常の単一チェーンテーブルの削除操作とは明らかに異なり、前駆ノードが見つからず、現在のノードを指すポインタを直接次のノードに指す書き方は一般的に誤りであるが、ここで採用されている参照パラメータにより、削除操作の正確性が保証される.
たとえば、単一チェーンテーブル内のすべての偶数ノードを削除する操作:
void Delete_even(struct node *&head){
  struct node *q,*tmp;
   tmp=head;
  while(tmp->next){
   if(tmp->next->res%2==0)
   {
    q=tmp->next;
    tmp->next=q->next;
    free(q);
   }
   else 
   tmp=tmp->next;
  }
}

依然として、前駆ノードを先に探します.
ここでは、前駆ノードが見つからない方法を示し、依然として参照パラメータと再帰を採用している.
void DeleteNode(struct node* &p){
   struct node *q;
   q=p;
   p=p->next;
   free(q);
}

void DeleteBFS(struct node * &p,int key){
   if(p->data==key){
     DeleteNode(p);
    return ;
   }
   else
    DeleteBFS(p->next,key);
}

総じて、ポインタに遭遇した場合、一般的に考慮すべき問題は、ポインタの指向を変更するか、ポインタが指す内容を変更することである(o(′▽`)o).
転載先:https://www.cnblogs.com/mlgjb/p/5763672.html