Error array type has incomplete element type

I have declared a struct, and I try to pass an array of those structs (as well as a double array of doubles, and an integer) into a function. I get an "array type has incomplete element type&q...

It’s the array that’s causing trouble in:

void print_graph(g_node graph_node[], double weight[][], int nodes);

The second and subsequent dimensions must be given:

void print_graph(g_node graph_node[], double weight[][32], int nodes);

Or you can just give a pointer to pointer:

void print_graph(g_node graph_node[], double **weight, int nodes);

However, although they look similar, those are very different internally.

If you’re using C99, you can use variably-qualified arrays. Quoting an example from the C99 standard (section §6.7.5.2 Array Declarators):

void fvla(int m, int C[m][m]); // valid: VLA with prototype scope

void fvla(int m, int C[m][m])  // valid: adjusted to auto pointer to VLA
{
    typedef int VLA[m][m];     // valid: block scope typedef VLA
    struct tag {
        int (*y)[n];           // invalid: y not ordinary identifier
        int z[n];              // invalid: z not ordinary identifier
    };
    int D[m];                  // valid: auto VLA
    static int E[m];           // invalid: static block scope VLA
    extern int F[m];           // invalid: F has linkage and is VLA
    int (*s)[m];               // valid: auto pointer to VLA
    extern int (*r)[m];        // invalid: r has linkage and points to VLA
    static int (*q)[m] = &B;   // valid: q is a static block pointer to VLA
}

Question in comments

[…] In my main(), the variable I am trying to pass into the function is a double array[][], so how would I pass that into the function? Passing array[0][0] into it gives me incompatible argument type, as does &array and &array[0][0].

In your main(), the variable should be:

double array[10][20];

or something faintly similar; maybe

double array[][20] = { { 1.0, 0.0, ... }, ... };

You should be able to pass that with code like this:

typedef struct graph_node
{
    int X;
    int Y;
    int active;
} g_node;

void print_graph(g_node graph_node[], double weight[][20], int nodes);

int main(void)
{
    g_node g[10];
    double array[10][20];
    int n = 10;

    print_graph(g, array, n);
    return 0;
}

That compiles (to object code) cleanly with GCC 4.2 (i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)) and also with GCC 4.7.0 on Mac OS X 10.7.3 using the command line:

/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c zzz.c

Can someone please help me understand what is the problem?

Arrays have the following properties:

  1. All its elements have the same size.
  2. The elements are stored contigously.

This allows to calculate the memory address of each element (e.g. id[i]) from the size and memory address of the first element and the index i.

To do this, the compiler needs to know how large the array elements are. When you declare the Vertex::edges[20] member, the compiler does not yet know, how large objects of type Edge are. Hence the compiler error.

One way to avoid this is, to define the Edge struct before the Vertex struct. In your case, this won’t help, because the Edge::target is of type Vertex and you will get a similar error. Memory addresses of struct members are calculated using the memory address of the object and adding the sizes of the members (and possibly some padding) that precede the requested member.

In such a case with circular dependencies, pointers as members can be used, because a pointer to a struct has the same size, no matter which members the struct has, that the pointer points to.

If the array is processed sequentially, and you have at least two reserved values (say NEXT and END), you can use

    const TYPE output_pin_enable[] = {
        /*  0 */ NEXT,
        /*  1 */ 1, 2, NEXT,
        /*  2 */ 3, NEXT,
        END
    };

Note that neither NEXT or END can appear as a value.  To process each enable, you do

    const TYPE *ptr;
    PINNUMTYPE pin;
    for (pin = 0, ptr = output_pin_enable; *ptr != END; ptr++) {
        if (*ptr == NEXT) {
            pin++;
        } else {
            /* Apply (*ptr) to pin (pin). */
        }
    }


If the list is sparse, or you cannot/do not want to use sequential pin numbers, you can do

    const TYPE output_pin_enable[] = {
        1,   1, 2, NEXT,
        5,   3, NEXT,
        END
    };

where the first value (and first value after each NEXT) indicates the element index, and END must be an invalid index (but may appear as a value); only NEXT must be an invalid value.  To process each enable,

    const TYPE *ptr = output_pin_enable;
    while (*ptr != END) {
        const PINNUMTYPE pin = *ptr;
        while (*(++ptr) != NEXT) {
            /* Apply enable (*ptr) to pin (pin). */
        }
    }


To find a specific enable sequence for a pin, you do need to scan through the array, in both above cases.  This means that non-sequential access (access to a specific pin, instead of each pin in the defined order), is relatively slow.

This kind of single-array structure is dense and useful when the accesses are sequential, and you don’t need random access to specific pin sequences.  They (Verlet lists) are used in e.g. molecular dynamic simulations, listing the neighbor atom identifiers as a list for each atom, so that interactions that are limited in range do not need to be calculated for all atom pairs/triplets/quads/groups in the system.  It offers a significant speedup for all non-trivial classical-type/non-quantum-mechanical atomic simulations.

This does not rely on any GCC-isms, and I originally saw it used in FORTRAN code.  In Simon’s case, I’d consider using the latter form, perhaps guarding some specific lines or line sets with

#ifdef FEATURE_OR_PINS … #endif

.

You could even split the pin identifier into two nibbles, high nibble (four bits) identifying the PORT (with END = 0xF0), and low nibble identifying the bit within the port (with NEXT = 0x0F).  Use an AND mask for the PORT (so that 0x00 = PORTA, 0x10 = PORTB, 0x20 = PORTC, and so on) instead of shifting it to low bits in a helper variable, for best efficiency; letting the compiler combine the bit shifts needed to get the correct address for the port control register.  This also means you can define and use macros  for each IO pin, as a single byte then identifies both the port and the pin within the port, with macro names matching whatever you use on the board silkscreen.)

Alex_fuse

2 / 2 / 3

Регистрация: 27.11.2012

Сообщений: 42

1

26.12.2012, 10:59. Показов 8965. Ответов 4

Метки нет (Все метки)


в функции выдает ошибку
arifm.c|4|error: array type has incomplete element type|

подправьте пожалуйста

main

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <stdlib.h>
#include "locale.h"
#include <time.h>
void arifm(int[], int, int);
int main()
{
    int n,m,i,j; //n - строка m - столбец
    setlocale(LC_CTYPE, "RUSSIAN");
    printf("Введите размер квадратной матрицы n*n: ");
    scanf("%d", &n);
    m=n;
    int mat[n][m];
    srand(time(NULL));
    for(i=0; i<m; i++)
    {
        for (j=0;j<n;j++)
        {
         printf(" %d", mat[i][j]=rand()%10);
        }
        printf("n");
    }
arifm((int) mat, n, m);
    return 0;
}

функция

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
 
void arifm(int mat[][] ,int n, int m)
 
{
int i, j;
double arr[n],sum=0.0;
for(i=0;i<m;i++)
{
    for(j=0;j<n;j++){
    sum=sum+mat[j][i];// вычисление суммы элементов столбца
    }
    sum=sum-mat[i][i];// вычитание элемента столбца по главной диагонали
    sum=sum/(n-1);//вычисление среднего арифметического
    arr[i]=sum;//присваивание значение sum элементу массива
    printf("среднее арифметическое столбцов: %.2fn",arr[i]);
    sum=0;
}
}

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



asidorchenko

387 / 214 / 102

Регистрация: 09.04.2012

Сообщений: 635

26.12.2012, 11:23

2

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#include <malloc.h>
 
void print(int** mat, int n, int m)
{
 int i, j;
 for(i=0;i<m;i++)
 {
  for(j=0;j<n;j++)
   printf("%d ",mat[i][j]);
  printf("n");
 }
}
 
void arifm(int** mat, int n, int m)
{
 int i, j;
 double sum;
 double* arr;
 
 sum = 0.0;
 arr = malloc(n*sizeof(double));
 
 for(i=0;i<m;i++)
 {
    for(j=0;j<n;j++){
    sum=sum+mat[j][i];// вычисление суммы элементов столбца
    }
    sum=sum-mat[i][i];// вычитание элемента столбца по главной диагонали
    sum=sum/(n-1);//вычисление среднего арифметического
    arr[i]=sum;//присваивание значение sum элементу массива
    printf("среднее арифметическое столбцов: %.2fn",arr[i]);
    sum=0;
 }
 free(arr);
}
 
 
int main()
{
    int** mat;
    int n,m,i,j; //n - строка m - столбец
 
    setlocale(LC_CTYPE, "RUSSIAN");
    printf("Введите размер квадратной матрицы n*n: ");
    scanf("%d", &n);
    m = n;
 
    mat = (int**) malloc( m * sizeof(int*));
    for(i = 0; i < m; i++)
     mat[i] = (int*) malloc( n * sizeof(int ));
 
    srand(time(NULL));
    for(i=0; i<m; i++)
    {
        for (j=0;j<n;j++)
        {
         printf(" %d", mat[i][j]=rand()%10);
        }
        printf("n");
    }
 
    print(mat, n, m);
 
    arifm(mat, n, m);
 
 
    for(i=0;i<n;i++)
     free (mat[i]);
 
    free(mat);
    return 0;
}



0



2 / 2 / 3

Регистрация: 27.11.2012

Сообщений: 42

26.12.2012, 11:37

 [ТС]

3

Спасибо большое



0



40 / 40 / 32

Регистрация: 24.11.2012

Сообщений: 200

26.12.2012, 18:59

4

Alex_fuse, а не могли бы пояснить причины ошибки?



0



2 / 2 / 3

Регистрация: 27.11.2012

Сообщений: 42

26.12.2012, 20:42

 [ТС]

5

Невнимательность и торопился.



0



Code:

 
In file included from contacts.c:19:0:
contactHelpers.h:54:35: error: array type has incomplete element type
contactHelpers.h:54:35: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:54:35: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
contactHelpers.h:63:34: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:66:35: error: array type has incomplete element type
contactHelpers.h:66:35: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:69:34: error: array type has incomplete element type
contactHelpers.h:69:34: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:72:24: error: array type has incomplete element type
contactHelpers.h:72:24: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:75:27: error: array type has incomplete element type
contactHelpers.h:75:27: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:78:27: error: array type has incomplete element type
contactHelpers.h:78:27: warning: �struct Contact� declared inside parameter list [enabled by default]
In file included from contactHelpers.c:23:0:
contactHelpers.h:54:35: error: array type has incomplete element type
contactHelpers.h:54:35: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:54:35: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
contactHelpers.h:63:34: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:66:35: error: array type has incomplete element type
contactHelpers.h:66:35: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:69:34: error: array type has incomplete element type
contactHelpers.h:69:34: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:72:24: error: array type has incomplete element type
contactHelpers.h:72:24: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:75:27: error: array type has incomplete element type
contactHelpers.h:75:27: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.h:78:27: error: array type has incomplete element type
contactHelpers.h:78:27: warning: �struct Contact� declared inside parameter list [enabled by default]
contactHelpers.c: In function �ContactManagerSystem�:
contactHelpers.c:178:4: error: type of formal parameter 1 is incomplete
contactHelpers.c:183:4: error: type of formal parameter 1 is incomplete
contactHelpers.c:188:4: error: type of formal parameter 1 is incomplete
contactHelpers.c:193:4: error: type of formal parameter 1 is incomplete
contactHelpers.c:198:4: error: type of formal parameter 1 is incomplete
contactHelpers.c: At top level:
contactHelpers.c:269:6: error: conflicting types for �displayContact�
contactHelpers.h:63:6: note: previous declaration of �displayContact� was here
contactHelpers.c:178: confused by earlier errors, bailing out

Code:

#ifndef contactHelpers_H


#define contactHelpers_H

// Clear the standard input buffer
// clearKeyboard:
void clearKeyboard(void);

// pause:
void pause(void);

// getInt:
int getInt(void);

// getIntInRange:
int getIntInRange(int minRange, int Maxrange);

// yes:
int yes(void);

// menu:
int menu(void);

// ContactManagerSystem:
void ContactManagerSystem(void);

// Generic function to get a ten-digit phone number:
// getTenDigitPhone:
void getTenDigitPhone(char[]);

// findContactIndex:
int findContactIndex(const struct Contact[], int, const char[]);

// displayContactHeader:
void displaycontactHeader(void);

// displayContactFooter:
void displayContactFooter(int);

// displayContact:
void displayContact(const struct Contact*);

// displayContacts:
void displayContacts(const struct Contact[], int);

// searchContacts:
void searchContacts(const struct Contact[], int);

// addContact:
void addContact(struct Contact[], int);

// updateContact:
void updateContact(struct Contact[], int);

// deleteContact:
void deleteContact(struct Contact[], int);

#endif // !contactHelpers_H

Code:

ifndef CONTACTS_H_
#define CONTACTS_H_

#include <stdio.h>


struct Name
{
    char firstName[31];
    char middleName[7];
    char lastName[36];
};

struct Address
{
    int streetNumber;
    char street[41];
    int apartmentNumber;
    char postalCode[8];
    char city[41];
};

struct Numbers
{
    char cell[11];
    char home[11];
    char business[11];
};

struct Contact
{
    struct Name name;
    struct Address address;
    struct Numbers numbers;
};

void displayTitle (void);

void getName (struct Name *);

void getAddress (struct Address *);

void getNumbers (struct Numbers *);

void getContact(struct Contact *);


#endif // !CONTACTS_H_

Code:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include "contacts.h"
#include "contactHelpers.h"

void printSectionHeader(const char*);

int main(void)
{
    ContactManagerSystem();

    return 0;
}

// Display specified test section header
void printSectionHeader(const char* testName)
{
    printf("n");
    printf("------------------------------------------n");
    printf("Testing: %sn", testName);
    printf("------------------------------------------n");
}

Code:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>


#include "contactHelpers.h"
#include "contacts.h"


// getName:
void getName(struct Name * name) {
    int yesNo = 0;
    printf("Please enter the contact's first name: ");
    scanf(" %[^n]", name->firstName);
    clearKeyboard();
    printf("Do you want to enter a middle initial(s)? (y or n): ");
    yesNo = yes();
    if (yesNo == 1) {
        printf("Please enter the contact's middle initial(s): ");
        scanf(" %[^n]", name->middleInitial);
        clearKeyboard();
    }

    printf("Please enter the contact's last name: ");
    scanf(" %[^n]", name->lastName);
    clearKeyboard();
}
// getAddress:
void getAddress(struct Address * address) {
    int yesNo = 0;
    printf("Please enter the contact's street number: ");
    address->streetNumber = getInt();
    if (address->streetNumber > 0) {
    }
    else {
        printf("*** INVALID INTEGER *** <Please enter an integer>: ");
        address->streetNumber = getInt();
    }
    printf("Please enter the contact's street name: ");
    scanf(" %40[^n]", address->street);
    clearKeyboard();
    printf("Do you want to enter an apartment number? (y or n): ");
    yesNo = yes();
    if (yesNo == 1) {
        printf("Please enter the contact's apartment number: ");
        address->apartmentNumber = getInt();
        if (address->apartmentNumber > 0) {
        }
        else {
            printf("*** INVALID INTEGER *** <Please enter an integer>: ");
            address->apartmentNumber = getInt();
        }
    }
    printf("Please enter the contact's postal code: ");
    scanf(" %7[^n]", address->postalCode);
    clearKeyboard();
    printf("Please enter the contact's city: ");
    scanf(" %40[^n]", address->city);
    clearKeyboard();
}

// getNumbers:
void getNumbers(struct Numbers * numbers) {
    int yesNo = 0;
    printf("Please enter the contact's cell phone number: ");
    getTenDigitPhone(numbers->cell);
    printf("Do you want to enter a home phone number? (y or n): ");
    yesNo = yes();
    if (yesNo == 1) {
        printf("Please enter the contact's home phone number: ");
        getTenDigitPhone(numbers->home);
    }

    printf("Do you want to enter a business phone number? (y or n): ");
    yesNo = yes();
    if (yesNo == 1) {
        printf("Please enter the contact's business phone number: ");
        getTenDigitPhone(numbers->business);
    }
}
// getContact:
void getContact(struct Contact * contact) {
    getName(&contact->name);
    getAddress(&contact->address);
    getNumbers(&contact->numbers);
}

Code:

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>


#include <string.h>
// ----------------------------------------------------------
#include "contactHelpers.h"
#include "contacts.h"


#define MAXCONTACTS 5


// clearKeyboard
void clearKeyboard(void)
{
    while (getchar() != 'n')
        ; 
}

// pause:
void pause(void)
{
    printf("(Press Enter to Continue)");
    clearKeyboard();
}

// getInt:
int getInt(void)
{
    char NL = 'x';
    int value = 0;
    int boolean = 0;

    scanf(" %d%c", &value, &NL);

    do {
        if (NL != 'n') {
            clearKeyboard();
            printf("*** INVALID INTEGER *** <Please enter an integer>: ");
            scanf(" %d%c", &value, &NL);
            boolean = 1;
        }
        else {
            boolean = 0;
        }
    } while (boolean == 1);
    return value;
}

// getIntInRange:
int getIntInRange(int minRange, int maxRange)
{
    int tstInteger;
    int boolean = 0;

    tstInteger = getInt();
    do {
        if (tstInteger < minRange || tstInteger > maxRange) {
            printf("*** OUT OF RANGE *** <Enter a number between %d and %d>: ", minRange, maxRange);
            tstInteger = getInt();
            boolean = 1;
        }
        else {
            boolean = 0;
        }
    } while (boolean != 0);
    return tstInteger;
}

// yes:
int yes(void)
{
    int boolean = 0;
    int result = 0;
    char input;
    char NL = 'x';
    do {
        scanf(" %c%c", &input, &NL);

        if (NL != 'n') {
            printf("*** INVALID ENTRY *** <Only (Y)es or (N)o are acceptable>: ");
            boolean = 1;
        }
        else {
            switch (input) {
            case 'Y':
            case 'y':
                result = 1;
                boolean = 0;
                break;
            case 'N':
            case'n':
                result = 0;
                boolean = 0;
                break;
            }
        }
    } while (boolean == 1);
    return result;
}

// menu:
int menu(void)
{
    int input = 0;
    printf("Contact Management Systemn");
    printf("-------------------------n");
    printf("1. Display contactsn");
    printf("2. Add a contactn");
    printf("3. Update a contactn");
    printf("4. Delete a contactn");
    printf("5. Search contacts by cell phone numbern");
    printf("6. Sort contacts by cell phone numbern");
    printf("0. Exitnn");
    printf("Select an option:> ");

    input = getIntInRange(0, 6);
    printf("n");

    return input;
}

// ContactManagerSystem:
void ContactManagerSystem(void)
{
    struct Contact contact[MAXCONTACTS] =
    { { { "Rick",{ '' }, "Grimes" },
    { 11, "Trailer Park", 0, "A7A 2J2", "King City" },
    { "4161112222", "2162223333", "4163334444" } },
    {
        { "Maggie", "R.", "Greene" },
        { 55, "Hightop House", 0, "A9A 3K3", "Bolton" },
        { "9051112222", "9052223333", "9053334444" } },
        {
            { "Morgan", "A.", "Jones" },
            { 77, "Cottage Lane", 0, "C7C 9Q9", "Peterborough" },
            { "7051112222", "7052223333", "7053334444" } },
            {
                { "Sasha",{ '' }, "Williams" },
                { 55, "Hightop House", 0, "A9A 3K3", "Bolton" },
                { "9052223333", "9052223333", "9054445555" } },
    };

    int menuInput = 0;
    int exitInput = 0;
    int boolean = 0;

    do {
        menuInput = menu();
        switch (menuInput) {
        case 1:
            displayContacts(contact, MAXCONTACTS);
            pause();
            printf("n");
            break;
        case 2:
            addContact(contact, MAXCONTACTS);
            pause();
            printf("n");
            break;
        case 3:
            updateContact(contact, MAXCONTACTS);
            pause();
            printf("n");
            break;
        case 4:
            deleteContact(contact, MAXCONTACTS);
            pause();
            printf("n");
            break;
        case 5:
            searchContacts(contact, MAXCONTACTS);
            pause();
            printf("n");
            break;
        case 6:
            printf("<<< Feature to sort is unavailable >>>n");
            pause();
            break;
        case 0:
            printf("Exit the program? (Y)es/(N)o: ");
            exitInput = yes();
            printf("n");
            if (exitInput == 1) {
                printf("Contact Management System: terminated");
                printf("n");
                boolean = 1;
            }
        }
    } while (boolean == 0);
}

// getTenDigitPhone
void getTenDigitPhone(char telNum[11])
{
    int needInput = 1;

    while (needInput == 1) {
        scanf("%10s", telNum);
        clearKeyboard();

        if (strlen(telNum) == 10)
            needInput = 0;
        else
            printf("Enter a 10-digit phone number: ");
    }
}

// findContactIndex:
int findContactIndex(const struct Contact contact[], int size, const char cellNum[])
{
    int i = 0;
    int output;
    for (i = 0; i < size; i++) {
        output = strcmp(contact[i].numbers.cell, cellNum);
        if (output == 0) {
            return i;
        }
    }
    return -1;
}

// displayContactHeader
void displayContactHeader(void) {
    printf("+-----------------------------------------------------------------------------+n");
    printf("|                              Contacts Listing                               |n");
    printf("+-----------------------------------------------------------------------------+n");
}

// displayContactFooter
void displayContactFooter(int totalContact) {
    printf("+-----------------------------------------------------------------------------+n");
    printf("Total contacts: %dnn", totalContact);
}

// displayContact:
void displayContact(const struct Contact* contact) {
    if (contact->name.middleInitial[0] != '') {
        printf("%s %s %sn", contact->name.firstName, contact->name.middleInitial, contact->name.lastName);
    }
    else {
        printf("%s %sn", contact->name.firstName, contact->name.lastName);
    }
    printf("    C: %-10s    H: %-10s    B: %-10sn", contact->numbers.cell, contact->numbers.home, contact->numbers.business);
    printf("       %d %s, ", contact->address.streetNumber, contact->address.street);
    if (contact->address.apartmentNumber > 0) {
        printf("Apt# %d, ", contact->address.apartmentNumber);
    }
    printf("%s, %sn", contact->address.city, contact->address.postalCode);
}

// displayContacts:
void displayContacts(const struct Contact contact[], int num) {
    int i;
    int totalContact = 0;

    displayContactHeader();

    for (i = 0; i < num; i++) {
        if (strlen(contact[i].numbers.cell) > 0) {
            displayContact(&contact[i]);
            totalContact++;
        }
    }
    displayContactFooter(totalContact);
}

// searchContacts:
void searchContacts(const struct Contact contact[], int num) {
    char cellNum[11];
    int contactIndex = 0;

    printf("Enter the cell number for the contact: ");
    getTenDigitPhone(cellNum);
    contactIndex = findContactIndex(contact, num, cellNum);

    if (contactIndex == -1) {
        printf("*** Contact NOT FOUND ***n");
    }
    else {
        printf("n");
        displayContact(&contact[contactIndex]);
        printf("n");
    }
}

// addContact:
void addContact(struct Contact contact[], int num) {
    char emptyIndex[11] = { '' };
    int newContact;
    struct Contact tempContact = { { { 0 } } };

    newContact = findContactIndex(contact, num, emptyIndex);

    if (newContact != -1) {
        getContact(&tempContact);
        contact[newContact] = tempContact;
        printf("--- New contact added! ---n");
    }
    else {
        printf("*** ERROR: The contact list is full! ***n");
    }
}

// updateContact:
void updateContact(struct Contact contact[], int i) {
    char contactInput[11] = { '' };
    int input = 0;
    int contactIndex;
    int contactIn;
    printf("Enter the cell phone number for the contact: ");
    getTenDigitPhone(contactInput);
    contactIndex = findContactIndex(contact, i, contactInput);
    contactIn = findContactIndex(contact, i, contactInput);

    if (contactIn == -1) {
        printf("*** Contact NOT FOUND ***n");
    }
    else {
        printf("nContact found:n");
        displayContact(&contact[contactIndex]);

        printf("Do you want to update the name? (y or n): ");
        input = yes();

        if (input == 1) {
            getName(&contact[contactIndex].name);
        }
        printf("Do you want to update the address? (y or n): ");
        input = yes();

        if (input == 1) {
            getAddress(&contact[contactIndex].address);
        }
        printf("Do you want to update the numbers? (y or n): ");
        input = yes();

        if (input == 1) {
            getNumbers(&contact[contactIndex].numbers);
        }

        printf("--- Contact Updated! ---n");
    }
}

// deleteContact:
void deleteContact(struct Contact contact[], int i) {
    char contactInput[11] = { '' };
    int input = 0;
    int contactIndex;

    printf("Enter the cell phone number for the contact: ");
    getTenDigitPhone(contactInput);

    contactIndex = findContactIndex(contact, i, contactInput);

    if (contactIndex == -1)
        printf("*** Contact NOT FOUND ***n");

    else {
        printf("nContact found:n");

        displayContact(&contact[contactIndex]);
        printf("n");

        printf("CONFIRM: Delete this contact? (y or n): ");
        input = yes();

        if (input == 1) {
            contact[contactIndex].numbers.cell[0] = '';
            printf("--- Contact deleted! ---n");
        }
    }
}

Проблема: следующий фрагмент кода компилируется хорошо (где оба типа структур определены):

typedef struct {
    int a;
    float b;
} member_struct;

typedef struct {
    int a;
    double b;
    member_struct c;
} outside_struct;

outside_struct my_struct_array[4];

Однако, если опустить typedef для «outside_struct»:

typedef struct {
    int a;
    float b;
} member_struct;

struct {
    int a;
    double b;
    member_struct c;
} outside_struct;

struct outside_struct my_struct_array[4];

Я получаю сообщение об ошибке: "array type has incomplete element type 'struct outside_struct'". И если я также отброшу typedef для member_struct, я получаю дополнительную ошибку: "field 'c' has incomplete type"

Вопрос: Почему это происходит? Здесь строго необходимо использовать typedef? В моем коде я никогда не использую typedef для структурных типов, поэтому я ищу способ избежать этого, если это возможно.

3 ответа

Лучший ответ

В этой декларации

struct {
    int a;
    double b;
    member_struct c;
} outside_struct;

Объявлен объект outside_struct безымянного структурного типа. Ни одна из структур с именем struct outside_struct не объявлена.

Таким образом, компилятор выдает ошибку в этом объявлении массива

struct outside_struct my_struct_array[4];

Потому что в этом объявлении вводится спецификатор типа struct outside_struct, который не определен. То есть в этом объявлении спецификатор типа struct outside_struct является неполным типом.

Вы не можете объявлять массив с неполным типом элемента.

Вместо объявления объекта outside_struct безымянной структуры вам нужно объявить структуру с тем же именем тега, что и

struct  outside_struct {
    int a;
    double b;
    member_struct c;
};


3

Vlad from Moscow
23 Ноя 2021 в 16:54

Если вы отбрасываете typedef, вам нужно вместо этого добавить структурный тег: struct outside_struct { ... };


2

Lundin
23 Ноя 2021 в 16:45

Typedef используется для создания дополнительного имени (псевдонима) для другого типа данных.

typedef int myInt; //=>equivalent to "int"
myInt index = 0; //=>equivalent to "int index = 0;"

Та же логика и для struct.

typedef struct myStruct {} myStruct_t; //=> equivalent to "struct myStruct {};"
myStruct_t myStructVariable; //=> equivalent to "struct myStruct myStructVariable;"

Syntaxe = «typedef type newAlias;»

« myStruct {} » — это новый тип, содержащий все типы, которые вы хотите (int, char …)


0

Tiago Martins
23 Ноя 2021 в 17:10

It’s the array that’s causing trouble in:

void print_graph(g_node graph_node[], double weight[][], int nodes);

The second and subsequent dimensions must be given:

void print_graph(g_node graph_node[], double weight[][32], int nodes);

Or you can just give a pointer to pointer:

void print_graph(g_node graph_node[], double **weight, int nodes);

However, although they look similar, those are very different internally.

If you’re using C99, you can use variably-qualified arrays. Quoting an example from the C99 standard (section §6.7.5.2 Array Declarators):

void fvla(int m, int C[m][m]); // valid: VLA with prototype scope

void fvla(int m, int C[m][m])  // valid: adjusted to auto pointer to VLA
{
    typedef int VLA[m][m];     // valid: block scope typedef VLA
    struct tag {
        int (*y)[n];           // invalid: y not ordinary identifier
        int z[n];              // invalid: z not ordinary identifier
    };
    int D[m];                  // valid: auto VLA
    static int E[m];           // invalid: static block scope VLA
    extern int F[m];           // invalid: F has linkage and is VLA
    int (*s)[m];               // valid: auto pointer to VLA
    extern int (*r)[m];        // invalid: r has linkage and points to VLA
    static int (*q)[m] = &B;   // valid: q is a static block pointer to VLA
}

Question in comments

[…] In my main(), the variable I am trying to pass into the function is a double array[][], so how would I pass that into the function? Passing array[0][0] into it gives me incompatible argument type, as does &array and &array[0][0].

In your main(), the variable should be:

double array[10][20];

or something faintly similar; maybe

double array[][20] = { { 1.0, 0.0, ... }, ... };

You should be able to pass that with code like this:

typedef struct graph_node
{
    int X;
    int Y;
    int active;
} g_node;

void print_graph(g_node graph_node[], double weight[][20], int nodes);

int main(void)
{
    g_node g[10];
    double array[10][20];
    int n = 10;

    print_graph(g, array, n);
    return 0;
}

That compiles (to object code) cleanly with GCC 4.2 (i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)) and also with GCC 4.7.0 on Mac OS X 10.7.3 using the command line:

/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c zzz.c

~ Answered on 2012-04-04 00:35:12

Понравилась статья? Поделить с друзьями:
  • Error baldi basics
  • Error array size missing in
  • Error baddrawable invalid pixmap or window parameter 9
  • Error array required but string found
  • Error bad system config info windows 10