ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
53271 Топик полностью
bialix (08.03.2006 21:56, просмотров: 1) ответил ReAl на Ответы (частично вопросом на вопрос)
мои ответы Безусловно, Вы, Александр, гораздо опытнее меня в деле Си-программирования. В этом я в очередной раз убедился, глядя на Вашу реализацию декодера 7битной упаковки-распаковки и трюком со switch. НО, вобщето своим первым вопросом я пытался поймать Вас на слове и показать, что вы даете неправильную задачу. Дело в том, что пример Ксении -- неправильный. И, думаю, Вы знаете почему. Объяснюсь для остальных. Я как и все на ее пример посмотрел "замыленным" взглядом, как на очень примитивную иллюстрацию утверждения "goto есть выход из вложенности больше или равно 2м". Посмотрел, мысленно кивнул и пошел читать другие посты. Но когда Александр меня начал брать на слабО и попросил повторить ее код без goto -- тут уж пришлось посмотреть на него внимательнее и увидеть, что он в сущности глупый и неправильный. Сделаем reverse-engineering и переведем код Ксении в словесное описание задачи. Я думаю, что она бы звучала так: определить, есть ли в массиве отрицательные элементы и вернуть соответствующий флаг. Если решать исходную задачу, а не тупо повторять чей-то код, то легко увидеть, что два вложенных цикла здесь использовать в сущности не нужно. Это просто по-инерции можно так написать. А вообще можно либо пройти с помощью указателя по всему массиву (это будет самый быстрый способ). Либо, если нужно знать кроме флага присутствия отрицательных элементов еще и индекс отрицательного элемента массива (я уже начинаю усложнять задачу), то и тут можно найти обходной маневр. Поскольку я много пишу на питоне, а не только на Си, то покажу небольшой пример в виде питон-кода:
for i,j in index_generator(M,N):
    if array[i][j] < 0:
        error = True
        break
Данный код подразумевает, что есть написанная функция-генератор index_generator(), которая умеет выдавать пары индексов для прохода по всему массиву. Конечно, с точки зрения питона выгоднее для решения этой задачи использовать возврат из вложенных циклов через return, поскольку питон более продвинутый и не имеет некоторых си-ограничений. Поэтому будем считать, что данный пример, только иллюстрация. (вобще-то это жизненный пример из одной из моих программ, когда мне нужно было сделать универсальный метод для обхода массивов по разным направлениям, но это уже, как говорится, другая задача и другая история). И я могу показать, что такой функциональности можно достичь на си, если учесть, что цикл for это синтаксический сахар для цикла while. Будет это так (положим, что i должен пройти от 0 до M, а j от 0 до N, также считаем, что M и N не равны 0):
i = j = 0;
error = 0;
while (i < M)
{
    if (array[i][j] < 0)
    {
        error = 1;
        break;
    }

    j++;
    if (j < N)
        continue;

    j = 0;
    i++;
};
Этот код немного неоптимален. Но пока оставим его так. Но это было простое частное решение для одной частной задачи. Поскольку недостатка в желающих усложнить задачу, я думаю, не будет, то сразу подниму руки и скажу: "да, не каждый алгоритм можно переписать подобным образом". В частности выход наружу из switch, вложенного в другой switch или цикл, так будет сделать трудно, скорее всего практически невозможно. Хотя буквально вчера я понял, что о конструкции switch я знаю не всё ;-) Теперь, Александр, по поводу Вашего усложнения задачи для двух циклов. Вы ее привели в очень обобщенном виде и это с одной стороны я могу использовать как зацепку, чтобы найти подмножество случаев, когда Вашу конструкцию можно развернуть в один цикл, а когда нет. По крайней мере один вариант я уже вижу. Но далее начнутся новые нагромождения ограничений, усложнений и условий "как надо". Давайте здесь остановимся и согласимся на том, что иногда для решения задачи нужно/можно попытаться найти более оптимальный алгоритм, а не пытаться прооптимизировать типовой/универсальный или написанный кем-то. В сущности эту мысль Вы же сами высказывали Romario в другой субветке этого же обсуждения. Теперь я хитро схватился за Ваше же оружие. ;-) Да, и еще. Я не стесняюсь использовать goto. Данный же маленький спор-состязание с Вами был скорее из спортивного интереса. Я Вас лично уважаю за Ваши познания. Но сам я язык Си как язык программирования, не очень люблю. "Я использую питон когда могу и си когда должен" (с) Эрик Реймонд.