5 хитростей на языке C, которые изменят ваше мнение…

Давно работаете с языком C и думаете, что освоили его? вот несколько трюков на Си, о которых никто не знает.

1. Объем типа данных:

Область видимости - это область, в которой можно получить доступ к переменной после ее объявления. большинство разработчиков C не знают, что тип данных также может иметь область видимости.

например, если вы хотите, чтобы ваш новый тип данных был доступен только внутри функции. вы можете определить этот тип данных только внутри этой функции.

#include <stdio.h>
void demo();
int main()
{
    enum day{Mon, Tue, Wed, Thur, Fri, Sat, Sun};
    demo();
    printf("The enum day values: %d\t%d\t%d\t%d\t%d\t%d\t%d",Mon , Tue, Wed, Thur, Fri, Sat, Sun); /*this won't compile*/
    return 0;
}
void demo()
{
    printf("this is the demo function\n");
    printf("The enum day values inside the demo function: %d\t%d\t%d\t%d\t%d\t%d\t%d",Mon , Tue, Wed, Thur, Fri, Sat, Sun);
}

если вы протестируете это на GCC, вы получите следующее:

2. Триграфы:

посмотрите на этот код, как вы думаете, он будет правильно компилироваться ?!

#include <stdio.h>

int main()
??<
    printf("Hello World!\n"); 
??>

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

Это называется Триграфы.

Викиучебники объясняют существование триграфов тем, что они были определены в разделе 5.2.1.1 стандарта C 1989 г. как решение проблемы отсутствия символов {,}, [,] и т. Д. На других человеческих языках, кроме английского. .

эти последовательности переведены на первом этапе компиляции (предварительной обработки) в их эквивалент в следующей таблице.

Sequence Replacement
======== ===========
  ??=         #
  ??(         [
  ??/         \
  ??)         ]
  ??'         ^
  ??<         {
  ??!         |
  ??>         }
  ??-         ~

Например:

printf ("Eh???/n");

будет заменен на:

printf ("Eh?\n");

если вы не хотите, чтобы его заменяли:

printf ("Two question marks in a row: ?\?!\n");

Примечание. Некоторые компиляторы просто игнорируют эти триграфы, например, в GCC вы должны использовать параметр компилятора - триграфы, чтобы иметь возможность их заменить.

3. Диграф:

обманул вас однажды, не обману снова, не волнуйтесь.

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

Digraph Equivalent
======= ==========
   <:       [
   :>       ]
   <%       {
   %>       }
   %:       #
  %:%:      ##

Например:

#include <stdio.h>
int main()
<%
    printf("Hello World! %> \n"); //this will not be modified
%>

Примечание: компилятор не смог идентифицировать% ›внутри строки и ожидал спецификатора формата.

4. Ярлыки на корпусе коммутатора - это просто ярлыки:

что вы думаете об этом коде? Можете ли вы ожидать, какой результат?

#include <stdio.h>
 
int main () {
/* local variable definition */
   char grade = 'B';
    int count =0;
   switch(grade) {
      case 'A' :
        do {
         printf("Excellent!\n" );
      case 'B' :
         printf("Well done\n" );
         count++;
        }while(count < 3);
   }
   printf("Your grade is  %c\n", grade );
   return 0;
}

если вы не знаете, проверьте следующее:

объяснение состоит в том, что ярлыки корпуса - это просто ярлыки. в каком порядке он выполняется, он ведет себя так же, подумайте еще раз, поведение очень нормальное.

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

5. Битовые поля без названия структуры:

Объявление битового поля без идентификатора объявляет безымянное битовое поле, которое не является членом и не может быть инициализировано. это можно использовать для заполнения, чтобы гарантировать, что никто не изменит значение этого поля. значение этого поля всегда будет нулевым.

если вы объявили безымянное битовое поле с нулевой шириной, это определит выравнивание следующего битового поля на границе выделения.

#include <stdio.h>
struct info
{
     char c1 : 1;
     char :7;
     char c2:1;
};
void main()
{
struct info f1;
printf("\n\n\tSize of info is : %d",(int)sizeof(f1));
}

Я считаю, что большая часть этой информации будет новой для большинства людей, поскольку она не используется в повседневном программировании.

Наконец, я надеюсь, что вам понравилось чтение, и дайте мне знать в комментарии, если вы когда-либо использовали один из них в своем коде.

Https://medium.com/@ahmhashesh/membership