Можно ли получить адрес переменной при выполнении математических операций с ней в одной строке - PullRequest
0 голосов
/ 25 сентября 2019

Я реализовывал функцию C для работы со строками.

В конце мне пришлось возвращать указатель на статическую строку, но перед этим первый элемент строки должен был быть установлен в '\ 0'

char *funct(...)
{
    static char string[30];
    .
    . //do some manipulations and possibly return here
    .
    string[0] = '\0';
    return string;
}

На данный момент все работает абсолютно нормально, но затем я хотел объединить последние две строки:

char *funct(...)
{
    static char string[30];
    .
    . //do some manipulations and possibly return here
    .
    return &(string[0] = '\0');
}

Затем я получил ошибку "lvalue требуется как унарный '&'операнд".Я предполагаю, что это так, потому что компилятор угрожает всегда в скобках как число, а не как переменная, и, как мы все знаем, вы не можете иметь адрес только из числа («return & ('\ 0');» неверно).

Мой вопрос абсолютно несущественен, но я все же хочу знать, можете ли вы обмануть компилятор (в моем случае, gcc), чтобы обрабатывать содержимое в скобках как переменную, а не как число

Заранее спасибо:)

Ответы [ 3 ]

3 голосов
/ 25 сентября 2019

На данный момент все прекрасно работает

Да, код пока выглядит нормально.

но затем я хотел объединить последние две строки

Почему?Это бессмысленно.

Затем я получил ошибку «lvalue Требуется как унарный» & «операнд».Я предполагаю, что это так, потому что компилятор угрожает всегда в скобках как число

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

Некоторые операторы в C возвращают результат, который является lvalue, а некоторые нет.Оператор = этого не делает.Из стандарта:

Оператор присваивания сохраняет значение в объекте, обозначенном левым операндом.Выражение присваивания имеет значение левого операнда после присваивания, но не является lvalue.

Так что вам не следует этого делать.Оставьте код таким, какой он был, и ничего не меняйте:

string[0] = '\0';
return string;

... но все же я хочу знать, можете ли вы обмануть компилятор

Эх, ну, С допускает всевозможные сумасшедшие вещи.Но это не значит, что вы должны это делать.Некоторые примеры кода, которые вы не должны писать:

// BAD, OBFUSCATED CODE, DON'T USE THESE

return *string = '\0', string;

return &string[*string = '\0'];

return &(0<:string:>=0)<:string:>;
1 голос
/ 25 сентября 2019

Если вы хотите объединить эти две строки, рассмотрите возможность написания функции со значимым именем вместо того, чтобы запутывать ваш код (или пытаться каким-то образом «обмануть» компилятор)

char *cleared(char *str)
{
    *str = '\0';
    return str;
}

, чтобы вы моглииспользуйте это как

char *funct(/*...*/)
{
    static char string[30];
    /*
        do some manipulations and possibly return here
    */
    return cleared(string);
}
1 голос
/ 25 сентября 2019

Если вам нужен такой составной оператор возврата, просто используйте оператор запятой

return string[0] = '\0', &string[0];

Или (то же самое)

return string[0] = '\0', string;

Или вы можете заключить выражение в скобки.

return ( string[0] = '\0', string );
...