Search
Write a publication
Pull to refresh

Comments 61

#include <iostream>

int main()
{
  unsigned char x = 0;
  do
  {
    std::cout << (int)x << std::endl;
    ++x;
  }
  while (x != 0);

  return 0;
}
На количество строк ограничений нет?

typedef unsigned char u8;

u8 i = 0;
while(1)
{
    cout << i;
    if(255 == i)
        break;
    else
        ++i;
};
добавил UPD к условию задачи на основе вашего решения
Я не возмущаюсь и не хочу оспорить условие (типа, неправильно вы собеседуете и всё такое — вам виднее), но хочу заметить, что тогда решение задачи превращается в «угадай, как надо написать».

Кроме того, в production-коде в отсутствие других условий я бы писал именно с if, чтобы не превращать код в головоломку.
Да, с первоначальной формулировкой условия — моя ошибка, извините
С моей точки зрения код с do-while — это не головоломка.
Мне, например, в вашем варианте не нравится магическое число 255 и выполнение if на каждой итерации цикла (я не имею в виду производительность). Все дело вкуса. Согласен, что вы предложили корректное решение. Но я бы в продакшн выпустил вариант do-while, также в отсутствии доп. условий. К слову, я встречал Code Style Guide, запрещающий использование do.
Ну как же «магическое»? В условии сказано — от 0 до 255. У меня в коде можно найти и 0, и 255, всё очевидно, в отличие от решения, в котором с первого раза даже не видно количество итераций цикла.
Но вас не устраивает. По той причине, что вы хотите ровно такое решение, которое эксплуатирует особенность беззнакового переполнения. Это я и называю «угадай, какое решение я хочу увидеть».
also без каста будут выводится символы с соответствующими кодами.
for(unsigned char i = 0; i <= 254; i == 0 ? std::cout << (int)i++ << std::endl << (int)i << std::endl : std::cout << (int)++i << std::endl);
UFO landed and left these words here
Хм, у меня не выводит, MSVC 2008.
Правда у моего решения два недостатка: шагов будет не 256, а 255, и один из вариантов условия использовал (? :).
#include int main()
{
for(unsigned char x = 0; x!=128; x++){
std::cout << x*2 << ' ' << x*2+1;
}
return 0;
}
Условие задачи не пробовали читать?

ровно по одному числу на каждом шаге цикла
А какие качества/способности демонстрирует решение/не решение этой задачи?

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

практическую проблему я упомянул не потому, что без приведенной задачи нельзя было решить эту проблему, а просто для того, чтобы уточнить, что задача не выдумывалась специально для собеседований
просто подобные проблемы могут возникать в специфичных областях в каких нибудь soc, когда люди биты экономят, в других областях обычно люди пишут for (int = 0… даже если итерируют до 10

Слово не везде 16 бит. Но, скорее всего все современные платформы позволяют выравнивать по байтам, но я в этом не уверен.
вроде 8битных систем уже совсем не осталось, 16 битные и те вымирают. какой смысл выравнивать меньше чем на разрядность процессора?

+ в примере переменная будет на стеке лежать
Да я с вами не спорю, я наоборот согласен. Просто я хотел сказать, что экономии памяти, скорее всего, не получится от использования меньшей разрядности.
Наверное, давать задачу «напечатать 2^32 чисел» было бы чересчур. Какие-нибудь переборы всего диапазона int встретиться могут, но их труднее превратить в упражнение.
так вроде обычный цикл…

for( unsigned char x=0; x <= 255; x++ )
cout << (int)x << endl;

— а-а… я попался :)

действительно тогда…
x=0
do
{
x++
}
while(x!=0)
да… я сперва написал… потом попробовал… и понял что «прокололся» :)

// do..while — работает
Сжульничаю немножко
for (unsigned char x = 0; static_cast<int>(x) + 1 < 256; x++)
{
std::cout<<x<<std::endl;
}
Исправил. Вот так лучше:
for (unsigned char x = 0; static_cast<int>(x) < 256; x++)
{
std::cout<<static_cast<int>(x)<<std::endl;
}
Очень красивое решение
Правда я его модифицировал
	for (unsigned char i = 0;  std::cout << (int) i++, i != 0;);


Ввожу дополнительное условие в UPD
Слишком много UPD для задачи на собеседование.
Я считаю корректным на собеседовании по C++ задавать вопросы по C
Да, но зачем в теме и тегах указывать C++?
Т.е. по вашему эта задача даст вам какое-либо нужное(!) представление о кандидате, rly? Вообще не вижу особых смыслов в таких «задачах» либо в «задачах» на знание упоротых особенностей языка, нужно знать основные методологии разработки, а не все заковыристые случаи. :)
Я прошу прощения, но эта задача дается на экзаменах по программированию на младших курсах. Задача проверяет знание циклов и типов данных, это азы. Да, тут можно попасться, но где заковыристый подвох, позволяющий оценить уровень программиста?
Подвох в том, что подвоха нет — и вопрос в том, сколько времени и усилий понадобится программисту, чтобы это осознать.
Ну и проверить, знает ли он do...while();
То, что можно обойтись циклом for() — красиво, но вносить печать в выражение проверки условия… что-то в этом не то.
Для MSVC 2008 вот такая конструкция работает, на других компиляторах не проверял (у ios_base есть operator void*()).

while(true && std::cout << (int)i++ << std::endl && i);
Извините, неправильно прочитал UPD2, я старался наоборот вывести в условии цикла. :)
Придумал решение вообще без цикла и без переменных.
Если кому интересно:
#include <iostream>
using namespace std;
 
template<unsigned char i>
void f()
{
    cout<<static_cast<int>(i)<<endl;
    f<i+1>();
}
 
template<>
void f<255>()
{
    cout<<255<<endl;
}
 
int main()
{
    f<0>();
    
    return 0;
 
}

О, такая задача в яндексе была. Вывести числа от 0 до 1000 без циклов. Первый вариант — рекурсия, второй только что увидел в вашем коде.
Еще такой вариант:
class A
{
 static int i;
public:
 A() { std::cout << i++ << ' '; }
};

int A::i = 0;

A a[1000];
Лучше в другую сторону сделать рекурсию, чтобы в main было f<255>();
Самые явные и простые решения уже показали, можно поизвращаться:
    struct Print {
        Print(unsigned char& i) { std::cout << (int)i++ << std::endl; }
        operator bool() { return true; }
    };
    unsigned char i = 0;
    while(Print(i) && i);
Вы зря так сформулировали. Сейчас звучит как «напечатать странным образом 256 цифирок». И еще добавили — мы этим на практике занимаемся.

У вас ведь на практике задача была другая: перебрать все значения типа данных Х использовав только одну переменную этого же типа.

Над первой формулировкой я бы затупил на собеседовании гарантировано, ибо не выглядит как практическая задача. А вторая — никаких вопросов не вызывает и легко решается — потому что, действительно, тривиальная вещь. Понимаете, о чем я? Вы так выявите не знание циклов, а использование творческого подхода там, где не нужно — предложенные тут варианты решений об этом и говорят.
Вот еще, до полной коллекции:
#include <stdio.h>

#define X0 printf("%d\n",x++)
#define X1 X0;X0;X0;X0;X0;X0;X0;X0
#define X2 X1;X1;X1;X1;X1;X1;X1;X1
#define X3 X2;X2;X2;X2
int main(){
    unsigned char x = 0;
    X3; 
}
Некоторые мои коллеги были бы в восторге :-) Кода мало, работает быстро.
А если использовать переполнение для своих нужд?
unsigned char i = 255;
do {
    std::cout << 255 - i << std::endl;
    i--;
}
while(i != 255);

PS Вычитание лишнее, просто экспериментировал
void doWork(unsigned char *val)
{
   printf("%d\n", (*val)++);
   1/(*val);
   doWork(val);
}

void main()
{
   unsigned char val=0;
   doWork(&val);
}

Без циклов. А выход по делению на 0 :)
Sign up to leave a comment.

Articles