Чи можемо ми писати коментарі в іменах змінних?


144

Якщо у мене є вищевказаний код, і я хочу порахувати жетони, це буде 14 або 13 жетонів?

Чи правильно писати коментар у назві змінної? Можна припустити , що int i, int a, int iaглобально визначено.


13
У "традиційному" C до ANSI, принаймні, як це реалізується GNUcpp -traditional , він би розширився до ia = 10;.
Nate Eldredge

37
яке цікаве питання - чому мені це ніколи раніше не спадало на думку?
StephenBoesch

178
@javadba: Тому що розсудливі люди не подумають робити щось таке?
jamesqf

5
Якщо ви дійсно хочете це зробити, ви можете перейти до Фортрана. Пробіл поза рядками видаляється на першому етапі синтаксичного аналізу.
mpez0,

3
Я збирався відредагувати заголовок на ".... в межах імен змінних ...", але потім зрозумів, що ви, можливо, мали на увазі "між". (Я хотів його відредагувати, оскільки відповідь на оригінальний заголовок - "Чому, очевидно!" Важливою частиною є "немає пробілів".) Чи буде заголовок "Чи коментує коментар (без пробілів) відокремлювати маркери в C?" висловити своє власне запитання?
Пітер - Відновити Моніку

Відповіді:


198

Коментарі видаляються під час фази 3 перекладу програми 1 : кожен коментар замінюється одним пробілом. тому коментар /*nt*/точно не є символом.

Якщо жоден з int, main, i, aабо returnвизначаються як попередня обробка макросів, аналіз програми виробляє 14 жетонів (не 13):

int main ( ) { i a = 10 ; return 0 ; }

Якщо iне визначено як тип із typedefоператором, існує синтаксична помилка, i aяка не відповідає правилу в граматиці C.

Отже, ви не можете писати коментарі всередині імен змінних, коментар розбиває ідентифікатор на 2 окремі маркери. Це справедливо для будь-якої попередньої обробки та маркера мови 2 .

Однак зверніть увагу, що ви можете вставляти коментарі в незвичні місця, наприклад, між одинарними операторами та їх операндом або між #директивою та попередньої обробки та її аргументами:

Але наведене вище визначення макросу не визначає функціональний макрос, а звичайний макрос, STATякий розширюється до ( a ) - 1.

Імена змінних, як і будь-який інший маркер, можна розділити за допомогою екранованих нових рядків. Екрановані нові рядки - це послідовності або за якими \негайно йде новий рядок. Ці послідовності видаляються з вихідного коду під час фази 2 перекладу програми. Їх основна мета - розбивати довгі визначення макросів на декілька рядків.

Нижче наведено фрагмент коду 3, який виробляє ті самі 14 лексем:

Зверніть увагу, як колоризатор коду пропустив нарізані та нарізані ключовими словами ключові слова та коментарі :)


1) Ця поведінка була вказана в ANSI-C, він же C89. Деякі стародавні компілятори мали дещо іншу поведінку, що призводило до вставки символів, але такі особливості представляють лише історичний інтерес.

2) Ви можете майже вставити коментар всередині рядкової константи, скориставшись тим, що сусідні константи рядків об'єднуються у фазі 6 перекладу програми: printf("Hello "/* my name is Luca */"world!\n");

3) Цей стиль презентації Різдвяної ялинки не призначений для використання в реальних програмах, він ілюструє, як зловживати можливостями обробки вводу C. Більш складні трюки перемогли у Міжнародному конкурсі затуманеного коду С


Цікаво, чому Стандарт вимагає, щоб символ зворотної косої риски, що продовжує рядок, не відокремлювався від нового рядка іншими пробілами, враховуючи те, що немає жодної іншої обставини, коли пробіли чи відсутність цих даних були б семантично значущими, а деякі формати текстових файлів можуть не вміти розрізняти рядки, які закінчуються пробілами, від рядків, які цього не роблять?
supercat

@supercat: Я згоден. Це також охоплює випадок, коли файли надходять із застарілих систем, які використовують послідовності CR LF як закінчення рядків, що спричиняє помилки компіляції в системах Unix, які не розпізнають екрановані нові рядки, що містять a \rдо \n. Проте є випадок, коли це може мати зворотний ефект: коментарі можуть містити символи \, за якими слід пробіли, зокрема, щоб уникнути вставлення рядка:const char *path = "C:\\"; // the default path is C:\ 
chqrlie

Стандарт не вимагає, щоб текстові файли підтримували пробіли в кінці рядка. Написання такого коментаря, The path is "C:\"який здається кращим, ніж значення коду, залежить від відстеження нових рядків.
supercat

1
З технічної точки зору, стандарт не пред'являє такої вимоги, оскільки часто ігнорувана фаза перекладу 1 дозволяє видаляти порожні пробіли з кожного рядка, якщо ця поведінка задокументована.
zwol

4
Ця відповідь робить довгий шлях, лише щоб довести, що дурних питань немає. Молодці.
Овербрид,

65

З лексичної точки зору коментар такий самий, як пробіли.

Розділ 6.4p3 стандарту С щодо лексичних елементів говорить:

... Маркери попередньої обробки можна розділити пробілами ; це складається з коментарів (описаних далі), пробілів (пробіл, горизонтальна вкладка, новий рядок, вертикальна вкладка та подача форми) або обох. ...

Більш конкретно, коментар перекладається в єдиний простір. Це зазначено в розділі 5.1.1.2p3:

Вихідний файл розкладається на маркери попередньої обробки та послідовності пробілів (включаючи коментарі). Вихідний файл не повинен закінчуватися частковою маркером попередньої обробки або частковим коментарем. Кожен коментар замінюється одним пробілом. Символи нового рядка зберігаються. Визначається, чи кожна непуста послідовність пробілів, крім нового рядка, зберігається або замінюється одним пробілом.

Для ілюстрації цього, якщо ви пропустите свій код через препроцесор, ви отримаєте:

Тож коментарі, як пробіли, служать для відокремлення токенів.

Це означає, що код міститиме 14 лексем, а не 13.


25

Результат буде таким, ніби ви написали:

ПРИМІТКА:


12

Див. Переклад (він же компіляція) Фаза 3 , крок 2: "Кожен коментар замінюється одним пробілом" .

Отже, концептуально, i/*nt*/aстає i aв цей момент.


Коментарі не призначені для розширеного обговорення; цю розмову переміщено до чату .
Machavity

1

просто перевірте, яка форма вашого шматка коду

матиме після попередньої обробки. Просто додайте прапор "-E" до вашого компілятора, gcc -E myscript.c, і ви отримаєте результат:

І, очевидно, ви можете зробити висновок про помилку.


-9

Так, ви можете це зробити. Коментарі будуть пропущені компілятором. Вони не вплинуть на змінну. Це буде так само, просто не забудьте закінчити теги коментарів.


5
"не вплине на змінну. Це буде так само" Те саме, що i aчи ia?
HolyBlackCat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.