Являются ли char и int взаимозаменяемыми для аргументов функции в C?

Я написал некоторый код, чтобы убедиться, что серийный номер является буквенно-цифровым в C, используя isalnum, Я написал код в предположении isalnum вход char, Все работало Тем не менее, после рассмотрения isalnum позже я вижу, что он хочет, чтобы вклад как int, Мой код в порядке, как я должен изменить его?

Если мне нужно измениться, что будет правильным способом? Должен ли я просто объявить int и установить его на char и передать его isalnum? Это считается плохой практикой программирования?

Заранее спасибо.

#include <stdlib.h>
#include <string.h>
#include <stdbool.h>bool VerifySerialNumber( char *serialNumber ) {
int num;
char* charPtr = serialNumber;if( strlen( serialNumber ) < 10 ) {
printf("The entered serial number seems incorrect.");
printf("It's less than 10 characters.\n");
return false;
}

while( *charPtr != '\0' ) {
if( !isalnum(*charPtr) ) {
return false;
}
*charPtr++;
}
return true;
}int main() {
char* str1 = "abcdABCD1234";
char* str2 = "abcdef##";
char* str3 = "abcdABCD1234$#";
bool result;

result = VerifySerialNumber( str1 );
printf("str= %s, result=%d\n\n", str1, result);

result = VerifySerialNumber( str2 );
printf("str= %s, result=%d\n\n", str2, result);

result = VerifySerialNumber( str3 );
printf("str= %s, result=%d\n\n", str3, result);
return 0;
}

Выход:

str= abcdABCD1234, result=1

The entered serial number seems incorrect.It's less than 10 characters.
str= abcdef##, result=0

str= abcdABCD1234$#, result=0

1

Решение

Вам не нужно менять это. Компилятор неявно преобразует ваш char для int прежде чем передать его isalnum, Функции как isalnum принимать int аргументы, потому что функции, такие как fgetc вернуть int значения, которые учитывают специальные значения, такие как EOF существовать.

Обновить: Как уже упоминали другие, будьте осторожны с отрицательными ценностями вашего char, Ваша версия библиотеки C может быть быть реализованным аккуратно, чтобы отрицательные значения обрабатывались без каких-либо ошибок во время выполнения. Например, glibc (реализация стандартной библиотеки C для GNU), по-видимому, обрабатывает отрицательные числа, добавляя 128 к int аргумент.* Однако вы не всегда сможете рассчитывать на isalnum (или любой другой <ctype.h> функции) спокойно обрабатывать отрицательные числа, поэтому привыкание не проверять было бы очень плохой идеей.

* Технически, это не добавление 128 к самому аргументу, а скорее использование аргумента в качестве индекса в массиве, начиная с индекса 128, так что передача, скажем, -57 приведет к доступу к индексу 71 массива. Результат такой же, так как array[-57+128] а также (array+128)[-57] указать на то же место.

9

Другие решения

Обычно хорошо пройти char значение функции, которая принимает int, Он будет преобразован в int с тем же значением. Это не плохая практика.

тем не мение, есть конкретная проблема с isalnum и другие функции C для классификации символов и преобразования. Вот это из ISO / IEC 9899: TC2 7.4 / 1 (выделено мной):

Во всех случаях аргумент является int, значение которого должно быть
представляемый как неподписанный символ
или должен быть равен значению
макрос EOF, Если аргумент имеет любое другое значение, поведение
не определено.

Так что если char является типом со знаком (это зависит от реализации), и если вы столкнулись с char с отрицательным значением, то он будет преобразован в int с отрицательным значением перед передачей в функцию. Отрицательные числа не могут быть представлены как unsigned char, Числа представимые в виде unsigned char являются 0 в UCHAR_MAX, Таким образом, у вас есть неопределенное поведение, если вы передаете любое отрицательное значение, кроме EOF бывает.

По этой причине вы должны написать свой код в C:

if( !isalnum((unsigned char)*charPtr) )

или в C ++ вы можете предпочесть:

if( !isalnum(static_cast<unsigned char>(*charPtr)) )

Этот пункт стоит изучить, потому что при первом знакомстве это кажется абсурдным: не проходите char к функциям персонажа.

Кроме того, в C ++ есть версия с двумя аргументами isalnum в шапке <locale>, Эта функция (и ее друзья) char в качестве входа, так что вам не нужно беспокоиться об отрицательных значениях. Вы будете удивлены, узнав, что второй аргумент — это локаль 😉

2

По вопросам рекламы [email protected]