0

私は次のコードを持っています:

typedef struct AdjMatrix
{
  int nodes;
  int **adjMat;
} graph;

typedef struct Edge
{
  int from,to,weight;
}Edge;


int main(){
  ...

  graph *g=(graph *)malloc(sizeof(graph));
  g-> adjMat = (int **)malloc(sizeof(int *) * vertices);
  for( i = 0; i < vertices; i++){
    g->adjMat[i] = (int *)malloc(sizeof(int) * vertices);
  }
 ...

 Edge *E = (Edge *)malloc(sizeof(Edge) * maxEdges);

 int nEdges = 0;
 for(i = 0; i < g->nodes ; i++){
    for(j= 0; j< g->nodes; j++){
            if(i <= j){
                    printf("%d\t%d\t%d\t\n",i,j,g->adjMat[i][j]);
                    E[nEdges].from = i;
                    E[nEdges].to = j;
                    E[nEdges].weight = g->adjMat[i][j];
                    nEdges++;
            }
            else
                    break;
    }
 }


}

ご覧のとおり、グラフgの要素には「->」でアクセスし、エッジEの要素には「。」でアクセスしています。グラフgの要素に「。」でアクセスすると、コンパイラがエラーをスローする理由がわかりません。または「->」によるエッジEの要素?説明してください

4

4 に答える 4

2

配列として使用Eし、その配列内の個別のメンバーはポインターではないため、要素にアクセスするにはドット演算子を使用する必要があります。

一方、gこれは単一のgraph構造体へのポインターであり、ポインターとして->演算子を使用します。

Eただし、配列をポインターとして、変数を配列としてアクセスできますg。たとえば、次の2つのステートメントはどちらもまったく同じです。

E[0].from = i;

(E + 0)->from = i;

gそして、次のような配列としてアクセスできます。

g[0].nodes = x;
于 2012-10-22T06:06:44.613 に答える
1

gは型graph*であると宣言されており、グラフへのポインタになっています。gこれは、ポインター逆参照演算子を使用する要素にアクセスする必要があることを意味します->

Eはポインタでもあり、この場合はEdge*ポインタからエッジへのポインタですが、配列セマンティクスを使用しています。E[nEdges]はポインタではありません.。つまり、演算子を使用する必要があります。

基本的に、配列セマンティクスを使用すると、変数のポインター性が失われます。

EタイプはEdge*E[x]タイプEdgeです。

于 2012-10-22T06:07:00.007 に答える
0

コードでは、gとeの両方が構造体へのポインターです。配列はポインタと同じように動作するため、e [nEdges]は実際には位置(e + 12 * nEdges)にあるエッジと同じです。e[0].fromはe->fromと同じになります。

于 2012-10-22T06:08:10.720 に答える
0

演算子は、->ポインターを逆参照してから.演算子を適用するためにポインターで使用されます。したがって、たとえば、a->bはと同等です(*a).b

あなたが言ったように、.演算子はメンバー変数にアクセスします。gとは両方ともEポインタであることに気づきましたが、->演算子が機能しない理由は、で演算子Eをすでに使用している場合に、これは逆参照としても機能するためです。たとえば、この行はと同等ですが、この場合に演算子を使用しようとすると、1つの間接参照が多すぎると同等になります。[]EE[nEdges].to(*(E + nEdges)).to->(*(*(E + nEdges))).to

于 2012-10-22T06:10:19.423 に答える