LINUX.ORG.RU

Вопрос по С


0

1

В следующем фрагменте кода

list_move_tail(&p->run_list, array->queue + p->prio);
поясните мне пожалуйста что такое array->queue + p->prio когда array->queue это struct list_head[140] а p->prio это int. Типа прибавление к указателю целого для получения нужного элемента массива?

...адреса нужного элемента.

rg-400
()

>поясните мне пожалуйста что такое array->queue + p->prio когда array->queue это struct list_head[140] а p->prio это int. Типа прибавление к указателю целого для получения нужного элемента массива?

в С запись

a[i]

эквивалентна

*(a + i)

потому возможен и такой хак:

i[a]

(в С сложение обладает свойством x+y === y+x)

PS: но это касается только C. В C++ скобки [] можно перезагружать, и оператор [] не имеет отношения к оператору +.

drBatty ★★
()

это просто кто-то научился очередному трюку в ссях. за такие написания лучше отстреливать ойца. код должен быть таким, чтобы его можно было читать, а не изучать. ну, хотя конкретно в этом случае не совсем что бы уж нечитабельный, но тем не менее запись a[i] была бы гораздо читабельней.

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

И действительно, просто какие-то хакеры ядра Linux «научились очередному трюку в сях».

a[i]

Это не эквивалентно приведённому примеру.

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

Ну если вы Си читать не можете... Извините...

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

&a[i] читабельнее?

base + offset никогда трюком не был, если кто ещё не научился.

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

садись, два.

$ cat ./arr.c 
#include <stdio.h>

int a[4];

int main(int argc, char *argv[])
{
	a[0] = 5;
	a[1] = 6;
	a[2] = 7;
	a[3] = 8;

	printf("value: [%d]\n", *(a+2));
	printf("value: [%d]\n", a[2]);
	return 0;
}

$ gcc -o arr ./arr.c
$ ./arr 
value: [7]
value: [7]
Deleted
()
Ответ на: комментарий от Deleted

Купи очки и найди в коде list_move_tail(&p->run_list, array->queue + p->prio); разыменование указателя во втором аргументе. Как найдёшь, пиши.

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

не напрягайтесь, я знаю как инициализировать массивы. здесь для простоты понимания написал так.

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

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

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

поясни свой «высер». мой камент хотя бы по теме был, о том, что лучше писать проще. но вот твой комментарий тяжело соотносится с тематикой обсуждения.

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

>совсем чумной?

Это не ты писал?

ну, хотя конкретно в этом случае не совсем что бы уж нечитабельный, но тем не менее запись a[i] была бы гораздо читабельней.

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

Вот именно. Обращение к массиву включает в себя две операции: сложение и разыменование. Очевидно, что оно не эквивалентно простому сложению.

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

речь о формате, а не конкретном написании. об этом на пост выше написал drBatty. мой камент о том, что писать нужно проще. уж на палцах вроде пояснил. как еще объяснить не знаю.

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

> мой камент хотя бы по теме был

4.2. ты бред написал, к сабжу никакого отношения не имеет. си иди учи, советчик.

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

Так, давай разберёмся:

a[i]


Это не эквивалентно приведённому примеру.


Ты с этим согласен или ты с этим не согласен? Если согласен, какой был смысл в твоей гневной отповеди? Если не согласен, то иди читай справочник.

речь о формате, а не конкретном написании


Программирование целиком состоит из конкретных написаний. Компьютер делает то, что написано, а не то, что программист думает, будто там написано. Уж мысли-то точно выражать программирование должно научить.

садись, два


Вместо этого адекватный человек написал бы, что просто забыл поставить &. Можно даже послать меня к черту или еще дальше — это понятно. Но зачем делать умное лицо и приводить пример кода, не имеющий отношения отношения к обсуждению — не понятно.



Что касается «проще».
1) &array->queue[p->prio]
2)array->queue + p->prio...
Второй вариант быстрее набирать и проще распарсить глазами.

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

>какой был смысл в твоей гневной отповеди?

эээээ... гневность? извини, если чем обидел, чесслово, не было даже и мысли. надо было нашпиговать смайлами :).

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

про «садись, два», это лишь ответ на твой «Ну если вы Си читать не можете... Извините...», не более :).

Программирование целиком состоит из конкретных написаний.

не спорю. но относительно работы с массивами, собственно, почему я говорю о читабельности кода. ты ведь наверняка знаешь, что в большинстве языков семантика обращения к массивам именно a[i], разве нет? финты, вроде array->queue + p->prio, это скорее сишные трюки. Потому я и говорю, что человеку зачастую проще видеть «обычную» (читай часто применимую) запись работы с элементами массива. Вот осюда и мессадж, про ойца и написание читабельного кода.

Надеюсь, теперь, когда (на мой взгляд) разночтения разъяснились, попробуй перечитать мой первый пост, и скажи, есть ли там что-то негативное или дурное, или все-таки суть поста адекватна?

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

>в большинстве языков семантика обращения к массивам именно a[i]

Правильный вариант:

в большинстве языков синтаксис обращения к элементу массива именно a[i]




финты, вроде array->queue + p->prio, это скорее сишные трюки


Это не финты и не трюки. Это часть языка, ровно такая же как и другие, определённые в языке операции для чисел, указателей и т.д. Программирование на Си требует понимания архитектуры компьютера, принципов работы процессора, адресации оперативной памяти и т.п. Если человек пишет на Си, подразумевается, что это понимание у него в достаточной степени присутствует. Может в первый раз вызвать затруднение код указатель + число, если программист не знаком со всеми тонкостями языка. Но после понимания первого примера, остальные такие же не должны вызывать ни малейшего затруднения.

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

Выключай уже дурочку.

в большинстве языков семантика обращения к массивам именно a[i], разве нет?


1. В сабже _нет_ обращения к массиву. В сабже есть вычисление адреса.
2. Какая в жопу разница, как там пишут в других языках?

финты, вроде array->queue + p->prio, это скорее сишные трюки.


3. Норкоман, сука, штоле?!?! Это стандартная для С/С++ арифметика указателей, тот кто её не знает - идет из /d/ в сад. Тех даунов, что пишут «&array[index]», надо пороть розгами до простетления.

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

полностью поддерживаю.

Приведу еще один аргумент в пользу a+i: нередко нужен one-past-the-end указатель (для обозначения конца массива) — то есть i равен количеству элементов в массиве. В этом случае a+i абсолютно легально по стандарту, в то время как &a[i] эквивалентно &*(a+i) и на мой взгляд тут уже не очевидно корректно это или UB?

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

что-то ума не приложу, где я высказал против стандарта или же отрицал стандарт. беседу вообще куда-то в сторону увело. если не составит труда, прочитай еще раз http://www.linux.org.ru/jump-message.jsp?msgid=5708731&cid=5709844 и покажи, где тут речь про стандарты? или мы теперь придираемся к слову «финты»? или я сказал что финты противоречат стандартам? суть вообще о другом, о читабельности *(a+i) и a[i]. Причем тут количество элементов в массиве.

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

> суть вообще о другом, о читабельности *(a+i) и a[i]

во-1, речь шла о читабельности a+i и &a[i]

во-2, я показываю, что первая нотация универсальна, в отличие от второй. Потому что a+i можно и нужно использовать когда i равно кол-ву элементов в массиве (как в примере: std::sort(a, a+n)), в то время как вторая нотация &a[n] в этом случае некорректна.

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

>суть вообще о другом, о читабельности *(a+i) и a[i]

Тотальное 4.2

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

> суть вообще о другом, о читабельности *(a+i) и a[i]

во-1, речь шла о читабельности a+i и &a[i]

во-2, я показываю, что первая нотация универсальна, в отличие от второй. Потому что a+i можно и нужно использовать когда i равно кол-ву элементов в массиве (как в примере: std::sort(a, a+n)), в то время как вторая нотация &a[n] в этом случае некорректна.

wtf?

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

>Тех даунов, что пишут «&array[index]», надо пороть розгами до простетления.
позволю не согласиться.
правильное прочтение выражения buf + i _в некоторых случаях_ требует еще знания типа указателя buf.

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

Позволю себе обобщить - правильное прочтение выражение вообще требует во всех случаях знания типа операндов.

А тип массива array что, передается телепатически с помощью магического знака «&»?

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

я не совсем то имел в виду.
запись &buf[i] однозначно можно интерпретировать, как обращение к определенному элементу заранее заданного типа.
запись buf+i изначально не подразумевает наличия каких-либо элементов.
(например, для void *buf, первая запись вообще не применима)

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

> запись &buf[i] однозначно можно интерпретировать

Можно, но долго. Три символа и две операции, да еще и противоположные по смыслу, вместо одной естественной операции - это fffffuuuuuu.

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

> (например, для void *buf, первая запись вообще не применима)

ээ.. а если я тебя скажу, что вторая запись для void* тоже не применима?

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

> Тех даунов, что пишут «&array[index]», надо пороть розгами до простетления.

Ну-ну, и что же такого неправильного в этой нотации, что использующий ее - даун?

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

> Три символа

Да, два лишних символа - это просто непосильный оверхед.

и две операции, да еще и противоположные по смыслу,

Просто глупости.

fffffuuuuuu.

Да, когда свои вкусы защищают в таком тоне - это ffffuuuu

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

Есть много людей, которые пишут в резюме о знании языка «C/C++» и опыте использования этого языка. Большинство этих людей не знаю и не понимаю арифметику с указателями, не понимают, как устроен стэк, как работать с функциями с переменным числом аргументов, не знают, что такое LE/BE, не слышали про ABI.

Вот именно такие люди и будут писать &array[index] для того, чтоб прибавить к адресу array смещение index * sizeof(*array).

Хорошо это или нет - не знаю. В принципе, если такая форма «более понятна» для широкого круга «программистов» - то ничего страшного здесь нет, кроме небольшого количества быдлокода.

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

> Большинство этих людей не знаю и не понимаю арифметику с указателями, не понимают, как устроен стэк, как работать с функциями с переменным числом аргументов, не знают, что такое LE/BE, не слышали про ABI.

Я всё это знаю и понимаю...

Вот именно такие люди и будут писать &array[index] для того, чтоб прибавить к адресу array смещение

...но как минимум иногда пишу &array[index]. Просто потому, что есть разница между арифметикой указателей и обращением к элементу массива (только не надо говорить, что в Си это одно и то же - я знаю).

И уж точно я не считаю даунами тех, кто пишет &array[index] всегда.

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

Ты немного не понял мою точку зрения.

Я считаю, про программист должен писать короткие, лаконичные программы и при том легко читаемые (людьми, естественно). Простые вещи должны делаться просто, их не нужно усложнять. Тем более в случае со встроенной в язык арифметикой.

Для того, чтоб добиться того, о чём я написал в предыдущем абзаце - нужно хорошо понимать и уметь использовать язык, на котором ты пишешь (знать общепринятые идиомы так же не помешает).

В случае с автором этого топика - вместо того, чтоб взять «букварь» по яызку Си он просто сложил «лапки» и пошёл спрашивать на форум. И я более, чем уверен, что автор топика «программирует» на Си. Неумение пользоваться справочной литературой (да и гуглом, в конце концов) - признак быдлокодеров.

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

> Я считаю, про программист должен писать короткие, лаконичные программы и при том легко читаемые (людьми, естественно).

нужно хорошо понимать и уметь использовать язык, на котором ты пишешь (знать общепринятые идиомы так же не помешает).

С этим как бы глупо спорить. Но часто школие (по возрасту или в душе) просто тщится выделиться своими глубокими «знаниями» Си, и пишет на нем непроверяемую компилятором кашу из адресной арифметики, инкрементов и преобразований типов, и читает лекции о том, что такое Си надо и как на нем надо писать. В особо запущенных случаях они еще и ссылаются на стандарт языка.

В случае с автором этого топика - вместо того, чтоб взять «букварь» по яызку Си он просто сложил «лапки» и пошёл спрашивать на форум.

Да бог с ним, с топикстартером. Как принято на ЛОРе, ему всё высказали в первых постах, а потом пошел флейм на вольную тему. В данном случае - нотация обращения к массиву против адресной арифметики.

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

> часто школие (по возрасту или в душе) просто тщится выделиться своими глубокими «знаниями» Си, и пишет на нем непроверяемую компилятором кашу из адресной арифметики, инкрементов и преобразований типов,

Каша - это куча лишнего и перемешеннаго как попало, без логики? Если так, то лишние операции как раз попадают под это определение

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

>> часто школие (по возрасту или в душе) просто тщится выделиться своими глубокими «знаниями» Си, и пишет на нем непроверяемую компилятором кашу из адресной арифметики, инкрементов и преобразований типов,

Каша - это куча лишнего и перемешеннаго как попало, без логики?

Нет, это малопонятный код.

Если так, то лишние операции как раз попадают под это определение

В записи &array[index] «лишняя» операция одна (2 «лишних» символа). Впрочем, для кого-то и одна операция - это «куча».

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

Анонимус всё разжевал и разложил по полочкам.

Просто потому, что есть разница между арифметикой указателей и обращением к элементу массива


Конечно она есть. И именно по этому не надо выдавать одно (a+b) за другое (&a[b]).

но как минимум иногда пишу &array[index].


Зачем? Что ты пытаешься сказать этой абракадаброй программисту, который будет читать твой код?

В записи &array[index] «лишняя» операция одна (2 «лишних» символа).


Слушай, доцент, у тебя мама был? Папа был? Формулы сокращенного умножения в школе проходил? Тогда зачем пишешь код _сложнее_, чем это надо?

Посмотри исходники хоть того же линуксового ядра - как часто там встречаетя такая нотация?

когда свои вкусы защищают в таком тоне


Это не вкусовщина, это элементарное требование к простоте кода. Я _очень_ терпим к наименованиям переменных, отступам, табопробелам, подчеркиваниям в именах членов и тому подобной вкусовщине. Но заумоподобная эклектика, за которой самом деле скрываются простейшие операции, - это плохо пахнущий код, который просто требует «перепеши меня!!».

LamerOk ★★★★★
()
3 февраля 2011 г.
Ответ на: комментарий от mskmsk1985

Offtop, но в старую тему не написать и контактов не указано в профиле. Нашел твою тему http://www.linux.org.ru/forum/development/5519881, скрипт не выполняется:

/build-toolchain /home/alex/toolchain-script/ [get]
Extract archives...Failed

build.log:
tar (child): linux-2.6.36.tar.bz2: Функция open завершилась с ошибкой: Нет такого файла или каталога
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

В чем может быть дело?

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

> tar (child): linux-2.6.36.tar.bz2: Функция open завершилась с ошибкой: Нет такого файла или каталога

В чем может быть дело?

В отсутствие файла, очевидно же.

/build-toolchain /home/alex/toolchain-script/ [get]

Если ты посмотришь исходный код скрипта, то увидишь:

if [ «$2» = «get» ]

То есть проверяется наличие «get», а не «[get]», и если таки есть «get», то файлы качаются, иначе нет. В твоем случае ничего не скачивалось, это объясняет отсутствие файла.

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

rival прав. У тебя архивов с исходниками нет, либо качай сам либо убери скобки у get и надейся что ниодин из файлов за несколько месяцев с серверов не уехал (Я в это искренне верю).

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