9 интересных трюков на Си, с которыми вы раньше не сталкивались

В этой статье мы рассмотрим несколько редких приёмов языка Си. О некоторых из них я раньше не слышал, и вы, скорее всего, тоже. Если ваш преподаватель или коллега хвастаются знанием Си, просто задайте им пару вопросов об этих трюках, и если они справятся, то они действительно шарят 🙂 

Используем возвращаемое значение scanf() для проверки конца файла

while(~scanf("%d",&n)) {
    /* Your solution */
}

Очень полезно в системах с автоматической проверкой, где подача входных данных заканчвается EOF.

"%m" как аргумент printf() выводит “Success”

printf("%m");

"%m" выводит “Success” только в том случае, когда errno == 0. Это сокращение для строкового представления последнего наблюдаемого состояния ошибок. Например, если функция выдаст ошибку до printf, вывод будет другим.

Неявная инициализация целых нулём и единицей

main(i){
    printf("g = %d, i = %d \n",g,i);
}

Вывод чисел от 1 до 200 без использования циклов, переходов и рекурсии

#include<stdio.h>
#define STEP1 step();
#define STEP2 STEP1 STEP1
#define STEP4 STEP2 STEP2
#define STEP8 STEP4 STEP4
#define STEP16 STEP8 STEP8
#define STEP32 STEP16 STEP16
#define STEP64 STEP32 STEP32
#define STEP128 STEP64 STEP64
#define STEP256 STEP128 STEP128

int n = 0;

int step()
{
    if (++n <= 200)
        printf("%d\n", n);
}

int main()
{
    STEP256;
    return 1;
}

C++ Sucks?

#include <stdio.h>
double m[]= {7709179928849219.0, 771};
int main()
{
    m[1]--?m[0]*=2,main():printf((char*)m);
}

Вы будете удивлены, но этот код выведет надпись “C++Sucks”, и вот тому объяснение.

А вы сталивались с оператором “спуска” -->?

На самом деле --> — это никакой не оператор, а комбинация двух операторов: -- и >. Разберёмся на примере:  в условии цикла переменная x уменьшается, но возвращается старое значение x, которое сравнивается с 0 оператором >.

int _tmain()
{
    int x = 10;
    while(x-->0) // x goes to 0
    {
        printf("%d ", x);
    }
    printf("\n");
}

Вывод:

9 8 7 6 5 4 3 2 1 0
Press any key to continue . . .

Магия scanf

scanf("%[^,]", a); // This doesn’t scrap the comma

scanf("%[^,],",a); // This one scraps the comma

scanf("%[^\n]\n", a); // It will read until you meet ‘\n’, then trashes the ‘\n’

scanf("%*s %s", last_name); // last_name is a variable

Сложение чисел без использования оператора +

int Add(int x, int y)
{
    if (y == 0)
        return x;
    else
        return Add( x ^ y, (x & y) << 1);
}

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

Перевод статьи «Interesting C Programming Tricks You didn’t know before»