Я работаю над небольшим проектом, чтобы действительно помочь мне понять, 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(), которые я мог бы использовать, однако, это для обучения, поэтому я работаю над созданием своих собственных функций по мере необходимости, чтобы увеличить образовательная ценность этих упражнений.
Чистый результат: «Я забыл включить мой файл заголовка» –
Ваш удивительный! Я не могу полагать, что это была опечатка. Полагаю, я должен быть благодарен, что это не было чем-то хуже. Просто из любопытства, почему он работал без указателя функции? –
@ AnthonyHopkins - компиляция с флагом '-Wall' покажет, что без указателя функции' GetString() 'предполагается как то, что ваш заголовочный файл определил бы. Но с указателем функции это предположение не выполняется. – alvits