C90 (gcc), 46 байт
r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}
Введення здійснюється через аргументи командного рядка (одне ціле число на аргумент), вихід - через вихідний код .
Спробуйте в Інтернеті!
Як це працює
r - глобальна змінна. Його тип за замовчуванням до int і, будучи глобальним, він значення за замовчуванням до 0 .
Аргумент функції c за замовчуванням також для int . Він буде містити ціле число n + 1 для масивів n булевих; перший аргумент main - це завжди шлях до виконуваного файлу.
Аргумент функції v оголошується як int**. Фактичний тип v буде char**, але оскільки ми розглянемо лише найменш значущий біт кожного аргументу, щоб повідомити символи 0 (кодова точка 48 ) та 1 (кодова точка 49 ), це не має значення для маленького ендіана машини.
Зменшення циклу while c і порівнює його з 0 . Як тільки c досягне 0 , ми вирвемося з циклу. Це потрібно, лише якщо масив не містить 0 's.
Поки 0<--cповертається 1 , ми беремо c- й аргумент командного рядка ( v[c]) і витягуємо його перший символ за допомогою перенаправлення покажчика ( *). Візьмемо побітові AND булевого 0<--cта кодового пункту символу (і три байти сміття, що слідують за ним), тому умова повернеться 0, коли зустрінеться 0 , вириваючись із циклу.
У останньому випадку, хоча аргументи командного рядка дорівнюють 1 , з r++кроком r на 1 , таким чином підраховуючи кількість кінцевих 1 -х.
Нарешті, c=rзберігає обчислене значення r у c . За допомогою налаштувань за замовчуванням компілятор оптимізує та видаляє призначення; він фактично генерує movl %eax, -4(%rbp)інструкцію. Оскільки retповертає значення регістру EAX, це генерує бажаний вихід.
Зауважте, що цей код не працює з C99, який повертає 0 з основного, якщо досягнуто кінця основного .
01100?