0

次の問題を解決するコードの書き方を理解するのに問題があります: 2D 配列を含む構造があります。次に、構造体へのポインターを引数として受け取る再帰関数があり、再帰関数がローカルコピーではなく、送信された構造体を操作できるようにしたいと考えています。

構造体は関数 initStruct で初期化され、そこで 2D 配列のメモリが割り当てられます。再帰関数は配列を構築し、特定のポイントで関数を呼び出して構造体の配列に挿入します。

コード:

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>

int** spBasis(int);
void mpBasis(int**, int, int, int, int, int, int, int*, struct mpBasis *, int, int);
void initMpBasis(struct mpBasis *, int, int);
void insertMpState(struct mpBasis *, int *);

struct mpBasis {
    int** basis;
    int size;
    int capacity;
};

int main() {
    int a, b, c, d;
    char maxE[256];
    char noParticles[256];
    char P[256];
    char M[256];
    FILE *fp;
    int **spStates;
    struct mpBasis *mp;
    int mpState[6] = {0, 0, 0, 0, 0, 0};

    printf("Input max e for sp states, no of particles, parity (1 for odd and 0 for even) and magnetic projection: ");

    gets(maxE);
    gets(noParticles);
    gets(P);
    gets(M);
    spStates = spBasis(atoi(maxE));
    fp = fopen("spStates.txt", "a+");
    fprintf(fp, "E\tj\tl\tm\n");
    for (a = 0; a < 330; a++) {
        fprintf(fp, "State %d: ", a+1);
        for (b = 0; b < 4; b++) {
            fprintf(fp, "%d\t", spStates[a][b]);
        }
        fprintf(fp, "\n");
    }

    mp = malloc(sizeof(struct mpBasis));
    initMpBasis(mp, 5449, 6);

    for (c = 0; c < 5449; c++) {
        for (d = 0; d < 6; d++) {
            fprintf(fp, "%d: %d\t", c, mp->basis[c][d]);
        }
        fprintf(fp, "\n");
    }

    printf("%p\n", (void*) mp);

    printf("hello 3");
    mpBasis(spStates, 0, atoi(maxE), 0, atoi(M), 0, atoi(P), mpState, mp, 0, 0); 

    fclose(fp);
    return 0;
}

int** spBasis(int maxE) {
    int c;
    int i, j, k, l;
    int q = 0;
    int** spStates;

    spStates = (int**)malloc(330 * sizeof(int *));
    for (c = 0; c < 330; c++) {
        spStates[c] = malloc(4 * sizeof(int));
    }

    for (i = 0; i <= maxE; i++) {
        for (j = i % 2; j <= i; j += 2) {
            for (k = -(2 * j  + 1); k <= (2 * j + 1); k += 2) {
                spStates[q][0] = i;
                spStates[q][1] = j;
                spStates[q][2] = 2 * j + 1;
                spStates[q][3] = k;
                q += 1;
            }
            for (l = -(2 * j - 1); l <= (2 * j - 1); l += 2) {
                spStates[q][0] = i;
                spStates[q][1] = j;
                spStates[q][2] = 2 * j - 1;
                spStates[q][3] = l;
                q += 1;
            }
        }
    }
    return spStates;
}

void mpBasis(int** spStates, int e, int maxE, int m, int M, int l, 
    int P, int * mpState, struct mpBasis *mpB, int position, int lastSpState) {
    int i;

    for (i = lastSpState; i < 330; i++) {
        if (e > maxE) {
            break;
        } else if (position == 5) {
            if (m == M && l % 2 == P) {
                 insertMpState(mpB, mpState);
                 break;
             }
        } else {
             // add spState to mpState and make the recursive call for the next position
            mpState[position] = i;
            mpBasis(spStates, e + spStates[i][0], maxE, m + spStates[i][3], M, 
                l + spStates[i][1], P, mpState, mpB, position+1, i);
        }
    }
}

void initMpBasis(struct mpBasis *a, int initialSize, int sizeY) {
    int c;
    a->basis = (int **)malloc(initialSize * sizeof(int*));
    for (c = 0; c < initialSize; c++) {
        a->basis[c] = (int *) malloc(sizeY * sizeof(int));
    }
    a->size = 0;
    a->capacity = initialSize;
}

void insertMpState(struct mpBasis *a, int* mpState) {
    /*if (a->size == a->capacity) {
        a->size *= 2;
        a->basis = (int **)realloc(a->basis, a->size * sizeof(int));
    }*/
    a->basis[a->size++] = mpState;
}

すべてのコードを追加しました。

問題は、再帰関数が呼び出された後、構造体 mpBasis の「basis」配列にまだランダムな値しか含まれていないことです。つまり、mpBasis 関数はそれに対して何もしていません。ここで mp 引数を値で渡していますか?

ご協力いただきありがとうございます!

4

1 に答える 1

0

最初のステップは、警告を有効にしてコンパイルすることです。たとえば、GCCを使用している場合は、オプション-Wall -Wextraを使用できます。

編集

(20を超えるエラーの以前のリストは削除されました)

OK、Visual Studioを使用しているので、次のような警告を有効にします。

  • プロジェクトの[プロパティページ]ダイアログボックスを開きます。
  • C /C++を選択します。
  • [一般]プロパティページで、警告レベルを/W4に変更します
于 2013-02-26T09:37:42.587 に答える