Суть драмы не уловил, но с for-ом там явная лажа, т.к. sizeof массива вернет размер в байтах, а не в элементах. for в статье будет всегда вылазить за границы массива.
было бы нормально если бы p был указателем на байт а так он в 4 раза больше памяти чем выделил испортит
2Booster смотрите int tab[1], *p; for (p = tab; p < tab + sizeof(tab)/sizeof(tab[0]); p++) { *p = 555; } sizeof(tab) вернет 400 p указатель на int тоесть плюс 1 к нему он уже на 4 сдвигается его можно только сдвинуть на sizeof(tab)/sizeof(tab[0]) тоесть на 100 плюc для каждого размер ссылки 4 и получится 400 байт а так получается 1600 байт затирает вместо 400
osox Что-то вы не то пишите. Откуда tab + sizeof(tab)/sizeof(tab[0])? По первой ссылке. Код (Text): for (p = tab; p < tab + sizeof(tab); p++) { ... }
2Booster это я переделал в правильный вариант как должно было быть ну или так еще можно было бы Код (Text): for (p = tab; p < (char*)tab + sizeof(tab); p++) { ... } а вы попробуйте у себя запустить изначальный ваиант сразу получите повреждение стека
Booster или например в отладчике посмотрите чему равен p после цикла вычтите из него базу массива и получите разницу 1600
osox То что арифметика адресная это понятно, но такое простительно, так как сразу не упомнишь где какой тип. Но в целом конструкция нормальная. В общем понятно чего хотел автор.
Хотя адресная арифметика в for как-то сомнительна. Никогда такое не применял и надеюсь не буду применять.
Booster Нет. Ненормальная. Подумай как следует над тем, куда будет указывать tab+sizeof(tab). Что такое `+' для указателей? Это когда одно из слагаемых -- указатель, а остальные целые, так? И целые измеряются в _элементах_. То есть tab+1 -- это указатель на первый элемент (на тот, который следует за нулевым). tab+sizeof(tab)/sizeof(tab[0]) -- это указатель на элемент с номером sizeof(tab)/sizeof(tab[0]), то есть на элемент следующий за последним. tab+sizeof(tab) -- это элемент расположенный далеко за границей массива. Booster Адресная арифметика -- это обоюдоострый инструмент. Не умея им пользоваться можно всё поломать. Но это не значит, что им не надо пользоваться. Надо _уметь_ им пользоваться и применять по делу.
r90 Ну не сообразил сразу, что тут адресная арфметика, каюсь. ^) Уж очень редко мне ей приходится пользоваться. Так же наверно и автор написал, неподумав. Объяснять что это такое мне не нужно.
r90 Код (Text): Адресная арифметика -- это обоюдоострый инструмент. Не умея им пользоваться можно всё поломать. Но это не значит, что им не надо пользоваться. Надо _уметь_ им пользоваться и применять по делу. А я что против. В примере явно без дела.
Сегодня компиляторы оптимизируют циклы таким образом, что индексы превращаются в арифметику адресов. Происходит это в RELEASE. Так что обычное (Kernighan & Ritchie) будет работать с тем же успехом (проверено на компиляторах Microsoft): Код (Text): for (int i=0; i < sizeof (tab) / sizeof (tab [0]); i++) { // // Далее в цикле использовать индекс // tab [i].<structure member> = ... ; // // Любая конструкция [b]tab [i][/b] будет оптимизирована в регистр, // так что арифметика адресов не требуется. // }
AsmGuru62 просто намного чаще удобней указателем обработать массив хотя иногда наоборот для указателя применяется нотация индексации массивов