Bagaimana Anda membuat array struct di C?

101

Saya mencoba membuat array struct di mana setiap struct mewakili benda langit.

Saya tidak memiliki banyak pengalaman dengan struct, itulah sebabnya saya memutuskan untuk mencoba menggunakannya daripada sejumlah array. Namun, saya terus mengalami banyak kesalahan berbeda. Saya telah mencoba menerapkan teknik yang telah saya lihat di berbagai utas dan di StackOverflow (seperti Array dari struct di C dan C - menginisialisasi array struct ), namun tidak semuanya berlaku.

Informasi lebih lanjut bagi mereka yang telah membaca sejauh ini: Saya tidak memerlukan semua ini untuk menjadi dinamis, saya tahu / menentukan ukuran semuanya sebelumnya. Saya juga membutuhkan ini menjadi array global karena saya mengakses ini dalam beberapa metode berbeda yang telah menetapkan argumen (yaitu metode GLUT).

Beginilah cara saya mendefinisikan struct di header saya:

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

Saya memiliki daftar variabel global lain yang saya definisikan sebelum saya mendefinisikan interior struct, dan salah satunya adalah array struct ini (pada dasarnya, jika saya terlalu tidak jelas dalam pembicaraan saya yang berkabut, baris di bawah ini di atas barang di atas):

struct body bodies[n];

Asal tahu saja, nadalah sesuatu yang telah saya definisikan secara sah (yaitu #define n 1).

Saya menggunakan array ini dalam beberapa metode berbeda, tetapi yang termudah dan paling sedikit memakan ruang adalah bentuk utama saya yang disederhanakan. Di sini saya menginisialisasi semua variabel di setiap struct, hanya untuk mengatur variabel dengan pasti sebelum saya memodifikasinya dengan beberapa cara:

  int a, b;
 for(a = 0; a < n; a++)
 {
        for(b = 0; b < 3; b++)
        {
            bodies[a].p[b] = 0;
            bodies[a].v[b] = 0;
            bodies[a].a[b] = 0;
        }
        bodies[a].mass = 0;
        bodies[a].radius = 1.0;
 }

Kesalahan saat ini yang saya hadapi adalah di nbody.c:32:13: error: array type has incomplete element typemana baris 32 adalah tempat saya membuat array struct.

Klarifikasi terakhir, yang saya maksud dengan header adalah ruang di atas int main(void)tetapi dalam *.cfile yang sama .

Amndeep7
sumber
Yah, itu bekerja dengan baik untukku. Apakah Anda tidak menyatakan struct body bodies[n];sebelum struct body {}deklarasi?
Jack
Perhatikan bahwa menggunakan array dengan panjang variabel seringkali dapat menyebabkan bug misterius atau crash ketika ukuran array melebihi ukuran tumpukan program di sistem Anda (yang sepenuhnya di luar kendali Anda sebagai programmer). Lebih baik menggunakan malloc () untuk hal semacam ini.
adrian

Jawaban:

107
#include<stdio.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

struct body bodies[n];

int main()
{
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}

ini bekerja dengan baik. pertanyaan Anda tidak terlalu jelas, jadi cocokkan tata letak kode sumber Anda dengan yang di atas.

nims
sumber
Juga, saya memiliki pertanyaan tentang penempatan antara deklarasi tipe struct dan kemudian benar-benar membuat contohnya - Saya memiliki struct yang berbeda, yang saya tentukan konten di bawah ini di mana saya pertama kali membuat instance darinya (hanya satu kali ini, bukan array), jadi mengapa ini tidak membuat serangkaian kesalahan besar? Ini berfungsi dengan baik, yang membuat saya berpikir bahwa upaya saya membuat array seharusnya berhasil juga, tetapi kali ini tidak berhasil. Juga, terima kasih atas jawaban Anda, itu berhasil.
Amndeep7
1
Hai, .... 59 suka? Saya tidak melihat array struct, saya hanya melihat array variabel dari
12

Saya pikir Anda juga bisa menulis seperti itu. Saya juga seorang pelajar jadi saya mengerti perjuangan Anda. Respon agak terlambat tapi ok.

#include<stdio.h>
#define n 3

struct {
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}bodies[n];
Christakitos
sumber
11

Jadi untuk menggabungkan semuanya dengan menggunakan malloc():

int main(int argc, char** argv) {
    typedef struct{
        char* firstName;
        char* lastName;
        int day;
        int month;
        int year;

    }STUDENT;

    int numStudents=3;
    int x;
    STUDENT* students = malloc(numStudents * sizeof *students);
    for (x = 0; x < numStudents; x++){
        students[x].firstName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].firstName);
        students[x].lastName=(char*)malloc(sizeof(char*));
        scanf("%s",students[x].lastName);
        scanf("%d",&students[x].day);
        scanf("%d",&students[x].month);
        scanf("%d",&students[x].year);
    }

    for (x = 0; x < numStudents; x++)
        printf("first name: %s, surname: %s, day: %d, month: %d, year: %d\n",students[x].firstName,students[x].lastName,students[x].day,students[x].month,students[x].year);

    return (EXIT_SUCCESS);
}
Dounchan
sumber
8
Haruskah lini malloc Anda memiliki jumlah Siswa * sizeof (STUDENT)?
Todd
@Todd Lebih baik tidak. sizeof *studentsadalah hal yang sama dan tidak akan salah jika STUDENT kebetulan berubah.
trentcl
@trentcl Dia telah mengalokasikan memori untuk {numStudents} jumlah petunjuk. Bukan struktur, tapi petunjuk. Ukuran pointer paling banyak biasanya 4 byte, sedangkan ukuran strukturnya adalah 20 byte. 20 byte adalah angka yang habis dibagi 4, jadi tidak diperlukan padding dan struktur disimpan pada setiap 20 byte dari alamat awal. Ini hanya berfungsi karena Anda mengalokasikan memori hanya untuk satu kasus tertentu. Jika tidak, mallocs lain dapat menimpa memori struktur Anda, karena tidak dialokasikan dan Anda telah meluap memori siswa Anda.
John Smith
3
@JohnSuara Anda salah; Baca lagi. sizeof *studentsadalah ukuran dari apa yang ditunjukkan , yaitu sizeof(STUDENT)bukan sizeof(STUDENT*). Anda membuat kesalahan persis yang ptr = malloc(num * sizeof *ptr)seharusnya dijaga oleh idiom itu. Periksa di sini (perhatikan server, seperti kebanyakan PC modern, memiliki 8 byte pointer sehingga ukurannya 8 dan 32, bukan 4 dan 20).
trentcl
@trentcl Terima kasih atas penjelasannya. Saya bingung dengan sintaks dereferencing pointer dalam inisialisasi itu sendiri. Saya akan mengatakan ini sedikit membingungkan, tetapi solusi yang pasti lebih kompak.
John Smith
8

pindah

struct body bodies[n];

untuk setelah

struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
};

Istirahat semua terlihat baik-baik saja.

vrk001
sumber
6

Cara lain untuk menginisialisasi array struct adalah menginisialisasi anggota array secara eksplisit. Pendekatan ini berguna dan sederhana jika tidak terlalu banyak anggota struct dan array.

Menggunakan typedef penentu untuk menghindari penggunaan kembali structpernyataan setiap kali Anda mendeklarasikan variabel struct:

typedef struct
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double mass;
}Body;

Kemudian deklarasikan array struct Anda. Inisialisasi setiap elemen sejalan dengan deklarasi:

Body bodies[n] = {{{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}, 
                  {{0,0,0}, {0,0,0}, {0,0,0}, 0, 1.0}};

Untuk mengulang, ini adalah solusi yang agak sederhana dan mudah jika Anda tidak memiliki terlalu banyak elemen array dan anggota struct besar dan jika Anda, seperti yang Anda nyatakan, tidak tertarik dengan pendekatan yang lebih dinamis. Pendekatan ini juga dapat berguna jika anggota struct diinisialisasi dengan enum-variabel bernama (dan bukan hanya angka seperti contoh di atas) dimana ini memberikan pembaca kode gambaran yang lebih baik tentang tujuan dan fungsi struktur dan anggotanya pada aplikasi.

Abdel Aleem
sumber
1
Suka ini! Jawaban yang bagus dan sederhana 👍
Ethan
1

Kesalahan itu berarti bahwa kompilator tidak dapat menemukan definisi tipe struct Anda sebelum deklarasi array struct, karena Anda mengatakan Anda memiliki definisi struct di file header dan kesalahan ada di nbody.ckemudian Anda harus memeriksa apakah Anda memasukkan file header dengan benar. Periksa milik Anda #includedan pastikan definisi struct sudah selesai sebelum mendeklarasikan variabel apa pun dari jenis itu.

David
sumber
saya ragu OP berarti header sebagai file header, saat dia menulis, "baris di bawah ini di atas barang-barang di atas" sebelum deklarasi array struct yang ada di file nbody.c-nya. Mari kita tunggu dia bangun dan menghapus keraguan.
nims
@nims benar, dengan header yang saya maksud adalah area di atas mainpernyataan tersebut.
Amndeep7
1

Solusi menggunakan pointer:

#include<stdio.h>
#include<stdlib.h>
#define n 3
struct body
{
    double p[3];//position
    double v[3];//velocity
    double a[3];//acceleration
    double radius;
    double *mass;
};


int main()
{
    struct body *bodies = (struct body*)malloc(n*sizeof(struct body));
    int a, b;
     for(a = 0; a < n; a++)
     {
            for(b = 0; b < 3; b++)
            {
                bodies[a].p[b] = 0;
                bodies[a].v[b] = 0;
                bodies[a].a[b] = 0;
            }
            bodies[a].mass = 0;
            bodies[a].radius = 1.0;
     }

    return 0;
}
Membantu Bean
sumber