2016-05-23 3 views
0

Я написал небольшую программу на C, которая собрана из нескольких файлов. Когда я компилирую, я получаю сообщение об ошибке «множественные определения».Несколько определений и первая определенная ошибка

Мой main.c:

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

#define FOREVER for(;;) 
#define INPUT_LEN 30 

int main() 
{ 
    char command[INPUT_LEN]; 
    char *func; 
    int i; 
    int t; 

    FOREVER 
    { 
     if(scanf("%s", command) == 1) 
     { 
      func = strtok(command, " "); 
      for(i=0;cmd[i].func != NULL;i++) 
      { 
       if(strcmp(func, cmd[i].name) == 0) 
       { 
        (*((cmd[i].func))); 
        t = 1; 
       } 
      } 
      if(t == 1) 
      { 
       printf("No such command"); 
      } 
     } 
    } 
    return 0; 
} 

Мой mat.c файл:

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

#define LENGTH 100 
#define SIXTEEN 16 
#define SIZE 4 


void read_mat() 
{ 
    int i = 0; 
    int j = 0; 
    int k = 0; 
    char tmp_name[LENGTH]; 
    char num_buffer[LENGTH]; 
    char *token; 
    double num_list[16]; 
    double tmp_num = 0; 

    scanf("%[^,], %s", tmp_name, num_buffer); 

    token = strtok(num_buffer, ","); 

    while(token != NULL) 
    { 
     if(strcmp(token, "0") == 0) 
     { 
      num_list[i] = 0; 
     } 
     else 
     { 
      tmp_num = atof(token); 
      if(tmp_num == 0)   
      { 
       printf("Error in parameter: %d\n", (i-1)); 
       break; 
      } 
      else 
      { 
       num_list[i] = tmp_num; 
      } 
     } 
    i++; 
    token = strtok(NULL, ","); 
    } 

    if(!strcmp(tmp_name, "MAT_A")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[0].mat[0][i][j] = num_list[k]; 
       k++; 
      } 

    } 
    else if(!strcmp(tmp_name, "MAT_B")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[1].mat[0][i][j] = num_list[k]; 
       k++; 
      } 
    } 
    else if(!strcmp(tmp_name, "MAT_C")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[2].mat[0][i][j] = num_list[k]; 
       k++; 
      } 
    } 
    else if(!strcmp(tmp_name, "MAT_D")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[3].mat[0][i][j] = num_list[k]; 
       k++; 
      } 
    } 
    else if(!strcmp(tmp_name, "MAT_E")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[4].mat[0][i][j] = num_list[k]; 
       k++; 
      } 
    } 
    else if(!strcmp(tmp_name, "MAT_F")) 
    { 
     for(i=0;i<SIZE;i++) 
      for(j=0;j<SIZE;j++) 
      { 
       mats[5].mat[0][i][j] = num_list[k]; 
       k++; 
      } 
    } 
    else 
    { 
     printf("No such matrix name."); 
    } 
} 

Мой general_structs.h файл:

#define SIZE 4 
#define SIZE_NAME 5 
#define SIZE_FUNC 10 

typedef double matrix[SIZE][SIZE]; 

matrix MAT_A, MAT_B, MAT_C, MAT_D, MAT_E, MAT_F; 

void read_mat(void); 

struct 
{ 
    char name[SIZE_NAME]; 
    matrix *mat; 
} mats[] = { 
     {"MAT_A", &MAT_A}, 
     {"MAT_B", &MAT_B}, 
     {"MAT_C", &MAT_C}, 
     {"MAT_D", &MAT_D}, 
     {"MAT_E", &MAT_E}, 
     {"MAT_F", &MAT_F}, 
     {"non", NULL} 
     }; 

struct 
{ 
    char name[SIZE_FUNC]; 
    void (*func)(void); 
} cmd[] = { 
     {"read_mat", read_mat}, 
     {"not_valid", NULL} 
     }; 

Мой макияж файл:

int_loop: my_math.o int_loop.o 
    gcc -g -ansi -Wall -pedantic my_math.o int_loop.o -o int_loop 

int_loop.o : int_loop.c 
    gcc -c -ansi -Wall -pedantic int_loop.c -o int_loop.o 

my_math.o : my_math.c 
    gcc -c -ansi -Wall -pedantic my_math.c -o my_math.o 

Я пытался решить эту проблему различными методами, но все же без успеха.

Ошибка я получаю это:

gcc -g -Wall -ansi -pedantic main.o mat.o -o mamantest 
mat.o:(.data+0x0): multiple definition of `mats' 
main.o:(.data+0x0): first defined here 
mat.o:(.data+0x70): multiple definition of `cmd' 
main.o:(.data+0x70): first defined here 
collect2: ld returned 1 exit status 
make: *** [mamantest] Error 1 

Почему возникает эта ошибка? Как я могу это решить?

Благодаря

ответ

1

В заголовочном файле вы определить переменные matscmd и, имея в виду как translation units (оба исходных файлов, которые включает в себя файл заголовка) будут иметь те, которые определены.

Переменные должны быть определены только в одном месте, в одном исходном файле, как

struct mat mats[7] = { ... }; 

выше определяет массив mats, и, как я сказал, должно быть сделано только в одном месте.

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

extern struct mat 
{ 
    ... 
} mats[7]; 

выше объявить переменная mats как массив из семи mat структур. Он также определяет структуру , поэтому его можно использовать, например, определить массив.


После модификации предложенных выше, полный файл заголовок должен выглядеть

// First header include guards (see https://en.wikipedia.org/wiki/Include_guard) 
#ifndef GENERIC_STRUCTS_H 
#define GENERIC_STRUCTS_H 

#define SIZE 4 
#define SIZE_NAME 5 
#define SIZE_FUNC 10 

typedef double matrix[SIZE][SIZE]; 

// Declare the variables (note the added use of the extern keyword) 
extern matrix MAT_A, MAT_B, MAT_C, MAT_D, MAT_E, MAT_F; 

void read_mat(void); 

// Define a structure named mat (note added structure tag name) 
struct mat 
{ 
    char name[SIZE_NAME]; 
    matrix *mat; 
}; 

// Define a structure named command (note added structure tag name) 
struct command 
{ 
    char name[SIZE_FUNC]; 
    void (*func)(void); 
}; 

// Now declare variables of the previous structures 
extern struct mat mats[7]; 
extern struct command cmd[2]; 

// End of header include guard 
#endif 

Этого заголовочный файл только декларирует переменные, и может быть включен во всех исходных файлах.

Тогда в одного исходного файла (например, ваш файл main.c) вы делаете фактические определения переменных:

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

matrix MAT_A, MAT_B, MAT_C, MAT_D, MAT_E, MAT_F; 

struct mat mats[7] = { 
    {"MAT_A", &MAT_A}, 
    {"MAT_B", &MAT_B}, 
    {"MAT_C", &MAT_C}, 
    {"MAT_D", &MAT_D}, 
    {"MAT_E", &MAT_E}, 
    {"MAT_F", &MAT_F}, 
    {"non", NULL} 
}; 

struct command cmd[2] = { 
    {"read_mat", read_mat}, 
    {"not_valid", NULL} 
}; 

#define FOREVER for(;;) 
#define INPUT_LEN 30 

int main() 
{ 
    ... 
} 

Важно, что вам нужно узнать здесь является то, что есть разница между декларирование и определение что-то.

Декларация в основном говорит компилятору, что «эта вещь существует где-то», и определение говорит компилятору «это is вещь».

Проблема заключается в том, что, если вещь уже не была объявлена, определение также является объявлением, и многие просто называют эти объединенные определения/объявления просто декларацией, которая немного путает всю концепцию.

+0

Если я это сделаю, у меня не будет файла $ .h (general_structs.h). Поскольку это часть задачи иметь один ... – JinKazama

+0

@JinKazama Вам по-прежнему нужен заголовочный файл для определений * структуры *, псевдонима типа 'matrix' и * деклараций * переменных. Вам просто нужно переместить * определения * этих переменных в один исходный файл. Обновлен мой ответ с измененным файлом заголовка. –

+0

Эй, спасибо за ваш очень информативный ответ. если «определяющая» часть структуры должна находиться только в одном исходном файле (например, «main.c»), тогда другой файл («mat.c») не будет знать эти структуры. Вот почему я предположил, что они должны быть в заголовке, где все источники могут приближаться и читать. Разве это неправильно? – JinKazama

Смежные вопросы