9

Вопрос по c – Почему эта C-программа компилируется без ошибок?

Я новичок в C, и я играл с C. Я набрал код на C так:

#include <stdio.h>
int main()
{
    printf("hello world\n"); 
    \
    return 0;
}

Хотя я использовал\ сознательно, компилятор C не выдает никакой ошибки. Для чего этот символ используется в языке Си?

Редактировать:

Даже это работает:

"\n";
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit ExceededcouldError: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от
  • На ваш главный вопрос ответили несколько раз. Что касается части о"\n";c программа - это (более или менее) список операторов. Буквальное значение (как3, или же"\n", или же"hamburgers") - совершенно правильное утверждение, даже если оно неdo что-нибудь.

    от jpm
  • & Quot; \ п & Quot ;; это заявление без какого-либо эффекта. Он полностью игнорируется компилятором и выдает предупреждение. Попробуйте скомпилировать с флагом gcc -Wall, который включает предупреждения компиляции.

    от dAm2K
5 ответов
  • 0

    Обратная косая черта просто экранирует следующий символ. В этом случае

    вероятно, символ конца строки (CR). Совершенно разумно.

  • 0

    Обратная косая черта \ интерпретируется препроцессором Си. Он защищает

    свой следующий символ (символ новой строки в вашем случае).

  • 0

    Обратная косая черта плюс то, что следует, это

    escape-последовательность; & Quot; \ п & Quot; вместе символ новой строки (печатает символ новой строки). Другим важным является & quot; \ t & quot ;, для таб.

  • 11

    Последовательность backslash-newline удаляется из кода на очень ранней

    стадии (фаза 2) процесса перевода. Раньше было то, как вы создавали длинные строковые литералы до того, как произошла конкатенация строк, и как вы по-прежнему расширяли макросы на несколько строк.

    См. & # XA7; 5.1.1.2 Этапы перевода стандарта C99:

    The precedence among the syntax rules of translation is specified by the following phases.5)

    Physical source file multibyte characters are mapped, in an implementation defined manner, to the source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences are replaced by corresponding single-character internal representations. Each instance of a backslash character (\) immediately followed by a new-line character is deleted, splicing physical source lines to form logical source lines. Only the last backslash on any physical source line shall be eligible for being part of such a splice. A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character before any such splicing takes place. The source file is decomposed into preprocessing tokens6) and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), the behavior is undefined. A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted. Each source character set member and escape sequence in character constants and string literals is converted to the corresponding member of the execution character set; if there is no corresponding member, it is converted to an implementation defined member other than the null (wide) character.7) Adjacent string literal tokens are concatenated. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit. All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment.

    5) Implementations shall behave as if these separate phases occur, even though many are typically folded together in practice.

    6) As described in 6.4, the process of dividing a source file’s characters into preprocessing tokens is context-dependent. For example, see the handling of < within a #include preprocessing directive.

    7) An implementation need not convert all non-corresponding source characters to the same execution character.

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

    Другая часть вашего вопроса, о:

    "\n";
    

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

    i = 1;
    

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

    Иногда вы найдете код, подобный следующему:

    *ptr++;
    

    Компилятор предупредит вас, что результат выражения отбрасывается; Выражение может быть упрощено до:

    ptr++;
    

    и достигнет того же эффекта в программе.

  • 4

    #define SHORT very log macro \

    \когда сразу же следует символ новой строки, он потребляется предварительной обработкой и вызывает следующий "физический" строка, которая будет присоединена к текущей логической строке. Это очень важно для написания длинных директив предварительной обработки, которые должны быть все в одной логической строке:

       consisting of lots and \
       lots of preprocessor \
       tokens
    

    Если вы удалите последовательности обратной косой черты-новой строки, это больше не правильно. Некоторые другие языки из культуры Unix имеют аналогичный синтаксис продолжения строки с обратной косой чертой: язык оболочки POSIX, производный от оболочки Bourne, а также make-файлы.

    $ this is \
    one shell command
    

    Около"\n";это основное выражение, используемое для формирования выражения-выражения. В C выражения могут использоваться как операторы, и это используется постоянно. Вашprintf Например, call - это выражение-выражение.printf("hello world\n") это постфиксное выражение, которое вызывает функцию, получая возвращаемое значение. Поскольку вы использовали это выражение в качестве выражения, возвращаемое значение выбрасывается. Возвращаемое значениеprintf указывает, сколько символов было напечатано, или было ли оно успешным вообще, поэтому, выбрасывая его, ваша программа забывает о том,printf звонок действительно сработал.

    Поскольку значение выражения-выражения отбрасывается, если такое утверждение также не имеет побочных эффектов, это бесполезное утверждение, которое ничего не делает (например, ваш"\n"). Но такие бесполезные высказывания не ошибочны. Если вы добавите параметры предупреждений в командную строку компилятора, вы можете получить предупреждение, например & quot; оператор без эффекта & quot; или что-то типа того.