#c #macros
#c #макросы
Вопрос:
Я написал код на C, подобный этому
#include<stdio.h>
#include<stdint.h>
#define CHAN(n) ((0x8020##4 n) ## 20)
void main()
{
int n = any_value;
printf("%x",CHAN(n));
}
Я получаю ошибку компиляции pasting ")" and "20" does not give a valid preprocessing token
.
На самом деле я хочу оценить выражение со значением n
. Итак, допустим, если я передаю значение n
as 1
, чем я ожидаю вывода 0x8020520
. Аналогично, если я передаю значение n
as 8
, чем я ожидаю 0x8020c20
.
Если я удаляю ##20
из макроса, я не получаю никакой ошибки компиляции и получаю ожидаемый половинный результат, например 0x80205
, или 0x8020c
Моя проблема в том, что я не могу найти способ объединить 20 после вычисления выражения (0x8020##4 n)##20
, т.е. Любая помощь будет оценена.
Комментарии:
1. Это не то, как работает препроцессор (он не может добавлять, а затем вставлять). В зависимости от вашего полного макроса это можно легко заменить некоторой математикой:
CHAN(n) (0x8020020 | ((4 (n)) << 8))
2. @Artyer: Вы можете сделать это ответом.
3. «Итак, допустим, если я передам значение n как 1, то я ожидаю вывода 0x8020520. Аналогично, если я передаю значение n как 4, чем я ожидаю 0x8020c20» Какой в этом смысл? Что здесь переменная, сдвиги или значения? Это не может быть и то, и другое одновременно. Эти два предложения противоречат друг другу.
4. @Lundin на самом деле
0x8020(4 n)20
является базовым адресом. Если я хочу вычислить следующий адрес, то это зависит от значенияn
. Я имею в виду, если я передаю значение n как 1, чем оно становится0x8020(4 1)20=0x8020520
. Аналогично, если мы передадим8
, чем это станет0x8020(4 8)20=0x8020c20
5. Но вы написали «если я передам значение n как 4, то я ожидаю 0x8020c20». Должно ли быть указано n = 8? Пожалуйста, отредактируйте и исправьте.
Ответ №1:
Когда вы это делаете (0x8020##4 n)
, он анализируется как эти токены: «(«, «0x8020» ## «4», » «, » n», «)».
После вставки «0x8020» и «4» вместе вы получаете ( 0x80204 n )
. На самом деле это не добавляется n
перед вставкой. (И как это могло быть? Препроцессор не знает, что такое переменная, и считает, что «n» — это просто строка длиной 1)
Когда вы это делаете ) ## 20
, вы получаете недопустимый токен «) 20», что не имеет смысла. Таким образом, он по праву выдает ошибку.
Похоже, вы хотите заменить одну шестнадцатеричную цифру значением n
. Вы можете легко сделать это с помощью побитовых операций:
#define CHAN(n) (0x8020020 | ((4 n) << 8))
// ^
(Где сдвиг перемещает единственную шестнадцатеричную цифру, представленную (4 n), на значение второго места, и |
(побитовое или)-ing оно заменит указанное 0.
Комментарии:
1. Я думаю, мы должны
<<
использовать 8 вместо 42. Но это не дает «если я передам значение n как 4, чем я ожидаю 0x8020c20». n = 4 дает
8020820
. Оказывается, вопрос не имеет никакого смысла и на него нельзя ответить.