Объявите каждый идентификатор перед его использованием
Код в вопросе вызывает функцию hexadecimal
в main
, но еще не объявил ее. В результате компилятор использует объявление по умолчанию, в котором hexadecimal
возвращает int
.
Более позднее определение hexadecimal
для возврата char
конфликтует с этим.
Исправитьдля этого либо переместите все определение hexadecimal
до main
, либо поместите объявление hexadecimal
перед main. Функция может быть объявлена с использованием той же строки, с которой начинается ее определение, за исключением того, что строка заканчивается ;
для объявления вместо списка операторов в скобках { ... }
для определения.
Tell YourИспользование компилятором современного стандарта C
В течение двух десятилетий стандарт C требовал объявления функций. Обратитесь к документации вашего компилятора, чтобы узнать, как указать компилятору использовать современный стандарт Си. Если вы используете GCC или Clang, вы можете использовать параметр командной строки -std=c17
, чтобы запросить стандарт на 2017/2018 C.
Сообщите компилятору предоставить предупреждения и ошибки и обратите на них внимание
Если вы используете GCC или Clang, используйте переключатель командной строки -Wmost
или -Wall
, чтобы включить много предупреждающих сообщений, и используйте -Werror
, чтобы превратить предупреждения в ошибки. Если вы используете другой компилятор, обратитесь к его документации.
Когда компилятор напечатает предупреждающее сообщение, выясните его значение и исправьте его, прежде чем продолжить.
Возвращает строку, а не символ
Функция, объявленная с char hexadecimal(char x[])
, возвращает только один char
. Вы хотите вернуть строку символов. Строка символов - это последовательность символов, оканчивающаяся нулевым символом.
Строки обозначаются указателями на их первый символ. Таким образом, базовый тип, используемый для ссылки на строку, равен char *
. Ваша функция должна быть объявлена как char *hexadecimal(char x[])
. (Он также может быть объявлен как char *hexadecimal(char *x)
, потому что параметр массива автоматически настраивается в качестве указателя.)
Создание нового объекта для возврата
Ваша функция определяет массив с char hex2[32];
и пытается вернуть его с return hex2;
. Объект, определенный таким образом внутри функции, имеет длительность автоматического хранения , что означает, что реализация C обеспечивает память для него в вызове функции и освобождает эту память, когда функция возвращается. Адрес автоматического объекта никогда не должен возвращаться из его функции, потому что его память больше не зарезервирована для использования (и потому что указатель технически становится недействительным).
Удалите char hex2[32];
и вместо этого используйте:
char *hex2 = malloc(32 * sizeof *hex2);
if (!hex2)
{
fprintf(stderr, "Error, malloc failed.\n");
exit(EXIT_FAILURE);
}
Это попытается выделить память с помощью malloc
. Если распределение завершится неудачно, он напечатает сообщение и завершит работу программы. Поскольку для этого используются новые подпрограммы из стандартной библиотеки, вы должны вставить это в начало вашей программы:
#include <stdlib.h>
Это выделяет память, но не освобождает ее. В больших программах, где управление памятью является проблемой, память должна быть освобождена. В этом случае вызывающая программа после завершения работы с памятью должна освободить ее, как с free(x);
, где x
- это char *
, который содержит значение указателя, возвращенное функцией.
Завершить строки нулевым символом
Конец строки отмечен нулевым символом. После того, как функция hexadecimal
поместит нужные символы в строку, она должна поставить нулевой символ в конце с:
hex2[i] = '\0';
Важно убедиться, что для этого символа есть место ввыделенное пространство - всегда включайте его в подсчет того, сколько места требуется.
Используйте правильные значения символов, а не жестко закодированные константы
Не используйте 48
для символа «0» или 55
за разницу между A
и десятью. Это не совсем соответствует C, и в этом нет необходимости, потому что C позволяет легко сделать этот код переносимым. Кроме того, жестко закодированные константы не передают намерение, тогда как использование символьных значений делает. Измените этот код:
if(temp<10)
temp += 48;
else
temp += 55;
на:
if (temp < 10)
temp += '0';
else
temp += 'A' - 10;
Это делает читателя намного более очевидным, каково намерение. Это все еще не полностью переносимо, потому что стандарт C (5.2.1 / 3 в проект C17 ) не не гарантирует, что символы «A» - «F» имеют последовательные значения вкодировка символов (для цифр от 0 до 9), но это улучшение.