LINUX.ORG.RU

Передача структуры в функцию на Си


0

1
struct watch {
    struct in_addr ipaddress; // remote ip
    int port; //remote port
    char *pathname; //file to be watched
};
typedef struct watch watch_t;

// file change handler will be called 
// when an event happens
// with parameters: watch details and the 
// event that occurred  on that watch
typedef void (*filechangehandler_t)(watch_t, int); << -- передаем структуру

Почему этот код не дает ошибку? Ведь передается не указатель на структуру, а - структура. Разве такое разрешено в Си?

★★★★★

А в чем, собственно, проблема?

unikoid ★★★
()

потому что у тебя пробел вместо подчёркивания.

anonymous
()

предыдущий анонимус пьян. Структуры тоже можно передавать, к слову.

anonymous
()

>Разве такое разрешено в Си?

Да

yoghurt ★★★★★
()

Вопрос только в том как именно происходит передача - чаще всего копированием в стек, но на некоторых архитектурах - передается адрес копии. В любом случае не особо быстро.

io ★★
()
Ответ на: комментарий от io

> но на некоторых архитектурах - передается адрес копии

а копия удаляется при выходе из функции автоматически?

pacify ★★★★★
() автор топика
Ответ на: комментарий от namezys

> ну копия расположена в той части стека, которая очищается при выходе из функи

Ок. Понял.
Вообщем, для учебных целей такое сгодится.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

для учебный целей лучше сгодится дизассемблер. рекомендую.
узнаете, почему в глобальном пространстве лучше делать
char m[]=«12345»;
вместо
char *m=«12345»;
а в локальном - наоборот.

xydo ★★
()
Ответ на: комментарий от xydo

> узнаете, почему в глобальном пространстве лучше делать
Вообще-то, это просто разные вещи. ИМХО подобные советы бессмысленны - исходить надо из реально требуемого.

svu ★★★★★
()

> Разве такое разрешено в Си?

Да, но в самых ранних версиях Си структру можно было передавать только по указателю.

anonymous
()
Ответ на: комментарий от xydo

Правильно здесь вам говорят, что это разные вещи. И чтобы это понять не дизассемблером надо пользоваться, а учить язык Си.

anonymous
()
Ответ на: комментарий от Eddy_Em

> char const *m = «12345»

Странный аналог у вас однако получаеся: в случае char m[]=«12345» можно изменять символы в m, а в вашем случае ничего менять нельзя.

Или вообще const char const *m = «12345».

Какой смысл наращивать кол-во квалификаторов 'const' слева от '*'? 'const' надо ставить либо слева, либо справа, либо одновременноо слева и справа от '*', а не наращивать их кол-во.

anonymous
()
Ответ на: комментарий от anonymous

Странный аналог у вас однако получаеся

А вот и нет: если мы пишем const char* c, это означает, что сам указатель может указывать куда угодно, но адресуемую им область памяти изменять нельзя. Если пишем char const *c, то это означает, что можно менять то, на что указатель указывает, но сам указатель менять нельзя (т.е. это и есть char c[]). Если же пишем const char const *c, то это значит, что ни указатель, ни указуемую область памяти менять нельзя.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Вероятно вы будете сильно удивлены, если узнаете, что const char * с, char const * с, const char const * с определяют одно и тоже - указатель на константу типа char. Повторяю еще раз: const нужно писать либо слева, либо справа, либо слева и справа от '*' одновременно. Учите матчасть Eddy_Em!

PS: если не разбираетесь в вопросе, то хотя бы у компилятора спросили бы

anonymous
()
Ответ на: комментарий от anonymous

Что-то C&R совсем другое говорили... (возможно, конечно, я ошибся, и для определения аналога char c[] надо писать не char const *c, а char * const c)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Что-то C&R совсем другое говорили...

Не слушайте вы этого C&R ибо православные сишники признают только K&R.

PS: cсылочку сюда кините на слова загадочного C&R?

anonymous
()
Ответ на: комментарий от anonymous

:) Я и имел в виду Кернигана и Ритчи.

Искать лень, по первой ссылке нашел вот что.

Действительно, чтобы сделать указатель, указуемые данные которого менять нельзя, надо писать char * const c, обшибся я. А const char * и char const * - одно и то же.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Спасибо за напоминание о способах написания const.
Обычно const не использую - привычка со времен изучения Паскаля. :)

pacify ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Правило использования const уже давно сформулировано: либо использовать везде, либо не использовать нигде.

anonymous
()
Ответ на: комментарий от namezys

Спешу тебя огорчить, но в С89/99 модификатор const не создает константу времени компиляции. Есть только два способа это сделать - литеральная коснтанта, обычно через препроцессор, либо перечисление.
Так что выбор не велик.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Это если какие-то макроопределения нужны разные. А если вам, скажем, double-константа нужна, лучше ее как const double определить, нежели через макрос.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Вообще-то те же K&R рекомендуют константы оформлять не как макросы, а именно как const type.

Ссылочку с рекомендациями дайте посмотреть, а то в K&R вроде как не было const.

anonymous
()
Ответ на: комментарий от namezys

> вот уж ужас. перечесления - это из времен, когда констант не было

Если вам нужно определить N кодов ошибок, то что вы выберете: константы или перечисления?

anonymous
()
Ответ на: комментарий от anonymous

> то что вы выберете: константы или перечисления?

Зависит от настроения.

Если кодов ошибок много - то enum.

Если мало - #define.

pacify ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Если вам нужно определить N кодов ошибок, то что вы выберете: константы или перечисления?

В С это не важно

namezys ★★★★
()
Ответ на: комментарий от anonymous

ishtar> 25.05, 17:19 /tmp Пожалуйста, все работает:

gcc --std=c99 1.c 
1.c:3: предупреждение: по умолчанию возвращаемый тип функции - 'int'
ishtar> 25.05, 17:19 /tmp
./a.out 
mass: text
ishtar> 25.05, 17:19 /tmp
gcc 1.c 
ishtar> 25.05, 17:19 /tmp
./a.out 
mass: text
ishtar> 25.05, 17:19 /tmp
cat 1.c
#include <stdio.h>
#include <string.h>
main(){
	const int sz = 5;
	char mas[sz];
	strcpy(mas, "text");
	printf("mass: %s\n", mas);
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

А погуглить - не?

google: kernigan ritchie const

Здесь, на стр.35 написано про const; на стр.39 написано про «защиту» аргументов функции при помощи const.

Про макросы лень искать.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

1) А что же вы массив при объявлении не инициализировали строчкой «text»?

2) Изначальным условием было использовать C89, поэтому добавьте пожалуйста ключики: -std=c89 -pedantic

anonymous
()
Ответ на: комментарий от anonymous

1) а мы так не договаривались =)

2)

gcc -std=c89 -pedantic  1.c 
1.c: В функции 'main':
1.c:5: предупреждение: ISO C90 forbids variable length array 'mas'
Все равно компилит.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> 1) а мы так не договаривались =)

Нет, так нет.

2) Все равно компилит

Компилит, не спорю, но только что там в варнинге белым по-черному написано?

anonymous
()
Ответ на: комментарий от Eddy_Em

> А погуглить - не?

Так забанили меня.

Здесь, на стр.35 написано про const; на стр.39 написано про «защиту» аргументов функции при помощи const.

Там упоминается про возможность использования const, но вы писали: «Вообще-то те же K&R рекомендуют константы оформлять не как макросы, а именно как const type». По приведенной вами ссылке на стр.35 и стр.39 я таких рекомендаций не нашел. Более того они даже в своих примерах не используют const, а макросы у них сплошь и рядом.

PS: раздел про const в K&R добавили только во втором издании, а кому хочется пересматривать и переделывать уже написанное. И если не ошибаюсь, то const и enum сначала появились в плюсах, а уже потом Страуструп уговорил добавить их в Си.

anonymous
()
Ответ на: комментарий от anonymous

Отвечу обоим анонимам: мне наплевать на стандарты c89 и c77, я использую c99, т.к. кое-что, к чему я привык, не работает в более ранних версиях.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Пожалуйста, все работает:

Ничерта не работает. Ты создал массив на стэке. Создай его в статической памяти. И да, можешь использовать С99.

LamerOk ★★★★★
()
Ответ на: комментарий от anonymous

> если не ошибаюсь, то const и enum сначала появились в плюсах


Частично ошибаешься. enum появился в С, причем очень рано, задолго до страуса с крестами.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

И таки шо? Я вообще предпочитаю с массивами не связываться. Если уж надо область памяти выделить, я предпочитаю malloc/calloc.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> И таки шо? Я вообще предпочитаю


Eddy_Em, мы тут не обсуждаем, кому что нравиться. Мы обсуждаем, что есть вычисление времени компиляции, и что есть вычисление времени выполнения.

И давайте без этих бурных эмоций. Мы ж не лисперы какие из соседней ветки...

:3

LamerOk ★★★★★
()
Ответ на: комментарий от Eddy_Em

Под этот срач надо было отдельную тему создавать. ))

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.