C ++: может ли int быть назначен символ *? - PullRequest
0 голосов
/ 29 августа 2010

Я читаю главу 2 Расширенного программирования Linux:
http://www.advancedlinuxprogramming.com/alp-folder/alp-ch02-writing-good-gnu-linux-software.pdf

В разделе 2.1.3 Using getopt_long приведен пример программы, которая выглядит примерно так:

int main (int argc, char* argv[]) {
  int next_option;
  // ...
  do {
    next_option = getopt_long (argc, argv, short_options, long_options, NULL);
    switch (next_option) {
       case ‘h’: /* -h or --help */
       // ...
    }
    // ...

Мое внимание привлекло то, что next_option объявлено как int. Функция getopt_long (), очевидно, возвращает int, представляющий короткий аргумент командной строки, который используется в следующем операторе switch. Как получается, что это целое число можно сравнить с символом в операторе switch?

Есть ли неявное преобразование из char (одного символа?) В int? Как действует приведенный выше код? (см. полный код в связанном pdf)

Ответы [ 6 ]

5 голосов
/ 29 августа 2010

Ни C, ни C ++ не имеют типа, который может хранить «символы» как значения с некоторыми выделенными символьно-специфическими свойствами.В этом смысле «символьный» тип не существует ни в C, ни в C ++.

В обоих языках C ++ и C char является целым типом.Он содержит чисел .Это просто наименьший (с точки зрения диапазона) целочисленный тип.Существует преобразование между char и int, точно так же, как оно существует между int и long или int и short.char не имеет специального статуса среди других целочисленных типов (кроме того факта, что тип char отличается от типа signed char).

Литерал формы 'h' в C ++ имеет тип char, но, как и любой другой интегральный тип, он сопоставим с int.Вот почему вы можете использовать его в case метке так же, как в исходном примере.

Другими словами, ваш оригинальный код такой же "странный", как и

switch (next_option) {
       case 1L: ...
       // ...
    }

быть.В этом случае аргумент switch - это int, а метка регистра - long.Код действителен.Вы находите это удивительным?Возможно нет.Ваш пример с 'h' не сильно отличается.

4 голосов
/ 29 августа 2010

Вы ошибаетесь - getopt_long(3) возвращает целое число.

1 голос
/ 29 августа 2010

Несколько функций возвращают int в C, но char в C ++.Возвращение int, когда char имело бы больше смысла, - просто старое культурное решение Си.Кроме того, в некоторых случаях необходимо, чтобы функция могла возвращать часовых, например, EOF.

0 голосов
/ 29 августа 2010

Думайте о символе как о 8-битном int.Вы можете выполнять целочисленные операции над символами и даже объявлять их как неподписанные.Вы не удивитесь, если сможете сравнить короткое и длинное.Почему сравнение char и int должно быть разным?

0 голосов
/ 29 августа 2010

Согласно man-странице, getopt_long возвращает int. И да, есть неявное приведение от char до int; char - это однобайтовое целочисленное значение.

Таким образом, в этом случае приведение происходит не при присваивании next_option, а в операторе case, где у вас есть константа символа, сравниваемая с int. Конечно, это предполагает, что вы компилируете это как C ++. В C ++ символьная константа имеет тип char, но в C она имеет тип int, поэтому, если вы скомпилируете этот код как C, преобразование типов вообще не будет.

(И в своем вопросе вы упомянули char*, но вы, вероятно, имели в виду char; здесь не используются указатели.)

0 голосов
/ 29 августа 2010

Как говорит другой ответчик, вы задаете здесь не тот вопрос.Но чтобы ответить на вопрос, который вы задали :

Нет неявного преобразования типа char * в int.На машинах x86 длина int и char * составляет 32 бита, поэтому «безопасно» явно приводить:

int x = (int*) &someChar;

НО ВЫСОКО НЕ РЕКОМЕНДУЕТСЯ !!!

На машинах x64, это не будет работать !int остается длиной 32 бита, но все указатели теперь имеют длину 64 бита ... так что вы потеряете данные в процессе!

...