Передача постоянного целого числа, когда функция ожидает указатель - PullRequest
5 голосов
/ 25 мая 2011

Какой наилучший / наиболее канонический способ передачи постоянного целочисленного значения в функцию, которая ожидает указатель?

Например, write функция

write (int filedes, const void *buffer, size_t size);

Скажем,Я просто хочу написать один байт (1), я бы подумал:

write (fd, 1, 1);

, но я, очевидно, получаю предупреждение

warning: passing argument 2 of 'write' makes pointer from integer without a cast

Я знаю, что могу

int i = 1;
write (fd, &i, 1);

но нужно ли это?Какой самый правильный способ сделать это без необходимости объявления / инициализации новой переменной?

Ответы [ 7 ]

10 голосов
/ 25 мая 2011

В C89 / 90 вы вообще не можете сделать это без объявления новой переменной. Особенность указателей в C состоит в том, что они всегда указывают на lvalues. Lvalue - это то, что находится в памяти. Таким образом, чтобы предоставить правильный аргумент для вашей функции, вам нужно что-то, что находится в памяти. Обычно это требует определения, то есть объекта, переменной. Константы в C не являются lvalues, поэтому вы не можете использовать константу там. Вещи, которые лежат между константами и переменными, являются литералами . C89 / 90 имеет только один вид литерала: строковый литерал . Строковые литералы являются lvalues, но не переменными. Таким образом, вы можете использовать строковый литерал в качестве второго аргумента write.

В C99 понятие литерала было расширено за строковые литералы. В C99 вы также можете использовать составные литералы для этой цели, которые также являются lvalues. В вашем примере вы можете вызвать вашу функцию как

write(fd, (char[]) { 1 }, 1)

Но эта функция доступна только в C99.

3 голосов
/ 25 мая 2011

В конкретном случае, на который вы ссылаетесь, вы можете сделать следующее:

write(fd, "\001", 1);

Но в целом вы должны сделать то, на что жалуетесь.Вы должны объявить объект, прежде чем брать его адрес:

 SomeType i;
 SomeFUnction(&i);
3 голосов
/ 25 мая 2011

Да, это необходимо. Нет другого способа сделать это в C, который был бы столь же понятен, поскольку вы не можете взять адрес / получить указатель на временный указатель.

(И, как уже сказал @rob, вы должны взять адрес char. Ваш пример непереносим.)

РЕДАКТИРОВАТЬ : См. Ответ @ AndreyT и установите ваш компилятор в режим C99.

1 голос
/ 25 мая 2011

Запись требует адрес как второй параметр - жить с ним.

1 голос
/ 25 мая 2011

Целое число не указатель.Если вы передадите ему один, он разыменует виртуальный адрес 1 и умрет.Вы должны сделать эту переменную и передать ее адрес.

0 голосов
/ 23 мая 2013
write(var, new int(4))

Это похоже на работу. Не уверен, насколько это хорошо, так как я не так часто использовал c ++. Дайте мне знать, если это плохой способ сделать это.

0 голосов
/ 25 мая 2011

Вы можете использовать drprintf(), который печатает в дескриптор файла.Он похож на fprintf(), который печатает в FILE *.

int dprintf(int fd, const char *format, ...);

Подробнее см. man 3 dprintf.

Функции dprintf () и vdprintf () (в библиотеке glibc2) есть точные аналоги fprintf (3) и vfprintf (3), за исключением того, что они выводят в файловый дескриптор fd, а не в поток stdio.

Это POSIX.1 совместимый, не универсальный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...