размер хранилища 's' неизвестен + указатель на указатель - PullRequest
1 голос
/ 31 марта 2012

Приветствие, Я столкнулся с ошибкой «Assignment_1.c: 10: 18: ошибка: размер хранилища« s »неизвестен». Я не эксперт в использовании указателя на указатель, я хочу иметь динамический размерный массив слов динамического размера ». Любая идея?

#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int size = MAX;
typedef struct{
    int numberOfWords,averageWordLength,id;
    char ** words;      
    }sentence;
void main(){  
    struct sentence s; 
    s.numberOfWords=3;
    s.averageWordLength=5;
    s.id=1;
    s->words= malloc(size * sizeof(s));
    //printf("%s",s.words);
    }

Ответы [ 3 ]

7 голосов
/ 31 марта 2012

Не используйте typedef для структур, если вы не пытаетесь создать непрозрачный тип. Это не верно. struct - отличный совет разработчикам языка Си. У Линуса было хорошее описание этого:

Ошибка - использовать typedef для структур и указателей. Когда ты см

vps_t a;

в источнике, что это значит?

Напротив, если оно говорит

struct virtual_container * a;

Вы действительно можете сказать, что такое "а".

Многие люди думают, что typedefs "помогают читабельности". Не так. Oни полезны только для:

(a) полностью непрозрачные объекты (где typedef активно используется для шкура что это за объект).

 Example: "pte_t" etc. opaque objects that you can only access using
 the proper accessor functions.

 NOTE! Opaqueness and "accessor functions" are not good in themselves.
 The reason we have them for things like pte_t etc. is that there
 really is absolutely _zero_ portably accessible information there.

(b) Очистить целочисленные типы, где абстракция помогает избежать путаница будь то int или long.

 u8/u16/u32 are perfectly fine typedefs, although they fit into
 category (d) better than here.

 NOTE! Again - there needs to be a _reason_ for this. If something is
 "unsigned long", then there's no reason to do

typedef unsigned long myflags_t;

 but if there is a clear reason for why it under certain circumstances
 might be an "unsigned int" and under other configurations might be
 "unsigned long", then by all means go ahead and use a typedef.

(c) когда вы используете sparse для буквального создания нового типа для типа проверка.

...

Не объявляйте кучу переменных в строке. Делая это, вы только путаете других.

И, конечно, вы не можете обратиться к полю участника с помощью оператора ., вы должны использовать ->. При этом ваш код должен выглядеть примерно так:

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

#define MAX 100

struct sentence {
    int numberOfWords;
    int averageWordLength;
    int id;
    char **words;
};

int main()
{
    struct sentence s;
    s.numberOfWords = 3;
    s.averageWordLength = 5;
    s.id = 1;
    s.words = malloc(MAX * sizeof(s));
    /* printf("%s",s.words); */
    return EXIT_SUCCESS;
}

Также рассмотрите возможность использования `слов в качестве первого члена структуры, или вы тратите память из-за смещения на платформах, где выравнивание указателя больше целого.

0 голосов
/ 31 марта 2012

Используйте '->', когда объект структуры имеет тип указателя. Это должно работать:

#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int size = MAX;
typedef struct{
  int numberOfWords,averageWordLength,id;
  char *words;
}sentence;

void main(){
  sentence s;
  s.numberOfWords=3;
  s.averageWordLength=5;
  s.id=1;
  s.words= malloc(size * sizeof(s));
  //printf("%s",s.words);
}
0 голосов
/ 31 марта 2012

В

typedef struct {
    int numberOfWords, averageWordLength, id;
    char **words;
    } sentence;

вы создаете безымянную структуру и псевдоним для этой структуры. Псевдоним называется sentence.

Теперь у вас есть новый тип в вашем коде. Имя нового типа sentence. Если вы предоставите тег, появятся 2 новых имени типа: sentence и struct tag.

typedef struct tag {
    whatever;
} sentence;

Также обратите внимание, что typedef на самом деле не нужен

struct tag {
    whatever;
};

Приведенный выше фрагмент кода определяет новый тип с именем struct tag.

...