2014-10-16 1 views
0

Я работаю над небольшим проектом, чтобы действительно помочь мне понять, c указательными/указательными функциями немного лучше. Приложение, над которым я работаю, состоит из 2 файлов источника (.c) и 1 файла заголовка (.h). Проблема я встречая следующая ошибка при попытке компиляции TurtleShell.c в файл «.o»:операции указателя функции между 2 c исходными файлами, вызывающими ошибки времени компиляции

[[email protected] TurtleShell]$ gcc -c TurtleShell.c -o TurtleShell.o 
TurtleShell.c: In function ‘main’: 
TurtleShell.c:12: error: ‘GetString’ undeclared (first use in this function) 
TurtleShell.c:12: error: (Each undeclared identifier is reported only once 
TurtleShell.c:12: error: for each function it appears in.) 

Как правило, от моего понимания, это означало бы, что я забыл объявить функцию, которая помещается после основного или что я забыл включить мой заголовочный файл как #include «GetString.h» и/или что заголовочный файл не находится в том же каталоге (или/usr/local/include,/usr/local) в качестве источника файл, использующий его, однако, три файла находятся в одном каталоге и объявлен заголовочный файл.

Следует отметить, что я пытаюсь получить доступ к GetString() с помощью указателя на функцию. Я использовал указатели функций в прошлом в том же исходном файле, но это мой первый реальный набег на использование нескольких исходных файлов для приложения, использующего указатели на функции, поэтому я сделал некоторые предположения в этом процессе. Исходный код выглядит следующим образом:

GetString.c:

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

/* 
This function handles getting a string from the user by allocating each 
character in the string to a char array. This array is guaranteed to 
grow as large as it needs as well as trim itself down to only the needed 
amount of memory to store the char array once the null terminator is 
processed. 
*/ 

int GetString(void) 
{ 
    //Set initial array length reasonably. size_t is used due to it's ability 
    //to allow an array to grow as large as it needs. 
    size_t strLength = 32; 
    char *stringPtr = malloc(strLength); 
    if (stringPtr == NULL) 
    { 
     fprintf(stderr, "Unable to allocate memory to hold char array. Exiting!\n"); 
     return 1; 
    } 
    printf("Enter some input: "); 
    int c = EOF; 
    unsigned int i = 0; 
    //Checks the value of c (user character input) to see if RETURN or CTRL+C/Z was entered 
    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     //Adds the character entered into the next index of the char array 
     stringPtr[i++] = (char) c; 
     //Check if we have reached the end of the allocated memory for the char array 
     if (i == strLength) 
     { 
      //multiply the current amount of memory allocated by 2. 
      strLength *= 2; 
      if ((stringPtr = realloc(stringPtr, strLength)) == NULL) 
      { 
       fprintf(stderr, "Unable to expand memory to hold char array. Exiting!\n"); 
       return 2; 
      } 
     } 
    } 
    //End of input. This adds the null terminator to terminate the char array 
    stringPtr[i] = '\0'; 
    //Check if we have any unused memory allocated for the array left. If so, we 
    //shrink it down to be the size of the input including the null terminator 
    if (sizeof(stringPtr) < strLength) 
    { 
     stringPtr = realloc(stringPtr, i); 
    } 
    printf("\n\nString value: %s\n\n\n", stringPtr); 
    //Memory cleanup time 
    free(stringPtr); 
    stringPtr = NULL; 
    return 0; 
} 

TurtleShell.c:

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

int main(void) 
{ 
    int running = 1; 
    while(running) 
    { 
     //Create a function pointer for GetString() so we can manipulate the outputted string from GetString 
     int (*GetStringPtr)(void); 
     GetStringPtr = &GetString; 
     char *string = malloc(GetStringPtr()); 
     free(string); 
     string = NULL; 
    } 
} 

GetString.h:

#ifdef GETSTRING_H_INCLUDED 
#define GETSTRING_H_INCLUDED 
extern int GetString(void); 
#endif 

Я знаю, что это имеет отношение к с тем, как я пытаюсь создать указатель на функцию, как если бы я изменял TurtleShell.c в следующем формате, он работает по назначению:

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

int main(void) 
{ 
    int running = 1; 
    while(running) 
    { 
     char *string = malloc(GetString()); 
     free(string); 
     string = NULL; 
    } 
} 

Я очень зелёный на C, поскольку я только писал в нем около 3 недель, поэтому мне может быть недостает чего-то очевидного. У меня проблема с Googled, но я нашел, что это особенно сложно правильно сформулировать, чтобы найти соответствующие результаты. Любая помощь приветствуется.

PS - Мне хорошо известно, что есть много хороших функций типа GetString(), которые я мог бы использовать, однако, это для обучения, поэтому я работаю над созданием своих собственных функций по мере необходимости, чтобы увеличить образовательная ценность этих упражнений.

ответ

2

#ifdef в Getstring.h должно быть #ifndef

+0

Чистый результат: «Я забыл включить мой файл заголовка» –

+0

Ваш удивительный! Я не могу полагать, что это была опечатка. Полагаю, я должен быть благодарен, что это не было чем-то хуже. Просто из любопытства, почему он работал без указателя функции? –

+0

@ AnthonyHopkins - компиляция с флагом '-Wall' покажет, что без указателя функции' GetString() 'предполагается как то, что ваш заголовочный файл определил бы. Но с указателем функции это предположение не выполняется. – alvits

1

Следующая строка не имеет смысла: символ * строка = таНос (GetString());

GetString() возвращает 0, 1 или 2. Это означает, что вы выделяете память длиной 0, 1 или 2 байта.

Если вы хотите получить строку, которую вы прочитали в GetString(), используйте аргумент, указатель на указатель на char. В этом случае вам не нужны указатели функций.

int GetString(char** string) 
{ 
    size_t strLength = 32; 
    *string = malloc(strLength); 
    ... 
} 

Не освобождайте строку в конце функции. Сделайте это в своей основной функции. Вы можете получить строку, передавая символ *, чтобы он функцию следующим образом:

char *string; 
int ret = GetString(&string); // Get the address of 'string' 
+0

Я ценю усилия, которые вы вложили в этот ответ, однако текущий код работает так, как предполагалось сейчас. Согласно вашему ответу, такое поведение было бы невозможным. Я что-то упускаю? –

+0

Переменная (указатель символа) 'string' в вашей основной функции никогда не укажет на введенную строку. Вместо этого он укажет на неинициализированную память. – nonplus

+0

@ AnthonyHopkins Какое "поведение"? С помощью Ремиса ваш код теперь компилируется. Но то, что он должен делать, все равно ускользает и от меня. Некоторые из ваших комментариев в коде просто не имеют смысла. Указатель функции не дает вам доступа к локальным переменным функции, но вы прокомментируете «основные» звуки, как это было вашим намерением. Вместо этого вы просто выделяете новый массив символов с длиной в соответствии со значением, возвращаемым GetString, как объяснил Йоханнес. Указатель функции не нужен даже для этого. – Oguk

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

  • Нет связанных вопросов^_^