Оператор Postfix вместе с оператором sizeof [duplicate]

Это может быть правдой, что:

  1. Кто-то использует каждую функцию языка / библиотеки, а
  2. . Переключение поведения здесь было бы непродуманным, но

полностью согласуется с обоими вышеперечисленными функциями и по-прежнему делает еще одну точку:

  1. Это запутанная функция, и это несчастливо в Python.

Другие ответы или, по крайней мере, некоторые из них либо делают точки 1 и 2, но не 3, либо делают точки 3 и нижние точки 1 и 2. Но все три являются истинными.

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

Существующее поведение не является Pythonic, а Python успешным, потому что очень мало о языке нарушает принцип наименьшего удивления где-нибудь возле , это плохо , Это настоящая проблема, было бы разумно ее искоренить. Это дефект дизайна. Если вы понимаете язык намного лучше, пытаясь проследить поведение, я могу сказать, что C ++ делает все это и многое другое; вы многому научитесь, перейдя, например, на тонкие ошибки указателя. Но это не Pythonic: людям, которые заботятся о Python достаточно, чтобы упорствовать перед лицом этого поведения, являются люди, которые тянутся к этому языку, потому что у Python гораздо меньше сюрпризов, чем на другом языке. Dabblers и любопытные становятся Pythonistas, когда они удивляются тому, как мало времени требуется, чтобы получить что-то работающее - не из-за дизайна fl - я имею в виду, скрытая логическая головоломка - которая урезает интуицию программистов, которые тянутся к Python потому что он просто работает.

477
задан razlebe 24 November 2011 в 17:16
поделиться

8 ответов

Из C99 Standard (акцент мой)

6.5.3.4/2

Оператор sizeof дает размер (в байты) его операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется по типу операнда. Результат - целое число. Если тип операнда - тип массива переменной длины, то операнд оценивается; в противном случае операнд не оценивается, а результат является целочисленной константой.

502
ответ дан Nawaz 21 August 2018 в 14:08
поделиться
  • 1
    & quot; Если тип операнда вл етс типом переменной длины, то операнд оцениваетс & quot; Вау! Я никогда не понимал, что – Kos 22 November 2011 в 13:13
  • 2
    что вы подразумеваете под массивом переменной длины? Это означает, что операнд - это массив? Код в этом случае не является массивом. Можете ли вы разобраться со мной? – Neigyl R. Noval 22 November 2011 в 13:19
  • 3
    Массив переменной длины - это массив, объявленный с размером, неизвестным во время компиляции, например, если вы читаете N из stdin и make int array[N]. Это одна из функций C99, недоступная в C ++. – Kos 22 November 2011 в 13:23
  • 4
    @LegendofCage, в частности это означало бы, что во что-то вроде sizeof(int[++x]) (действительно, действительно плохая идея, во всяком случае) можно оценить ++. – Jens Gustedt 22 November 2011 в 14:01
  • 5
    См. Пример использования VLA в http://ideone.com/Q89QP . – pmg 22 November 2011 в 15:29

Выполнение не может произойти во время компиляции. Поэтому ++i / i++ не будет. Также sizeof(foo()) не будет выполнять функцию, но вернет правильный тип.

175
ответ дан codaddict 21 August 2018 в 14:08
поделиться
  • 1
    Только иногда - это время компиляции, если это возможно. – Martin Beckett 22 November 2011 в 19:09
  • 2
    & quot; Выполнение не может произойти во время компиляции. & quot; что вы имеете в виду? – curiousguy 23 November 2011 в 02:58
  • 3
    Компиляция создаст только код объекта ... Код объекта будет выполнен только тогда, когда пользователь выполнит двоичный код. Поскольку sizeof происходит во время компиляции, предполагая, что i ++ будет увеличиваться, это неверно. – rakesh 23 November 2011 в 09:35
  • 4
    & lt; i & gt; & lt; i & gt; Поскольку sizeof происходит во время компиляции & quot; вы имеете в виду: & quot ;, поскольку sizeof является выражением постоянной времени компиляции & quot ;? – curiousguy 23 November 2011 в 10:18
  • 5
    Как & quot; # define & quot; происходит во время предварительной обработки, аналогично sizeof будет происходить во время компиляции. Во время компиляции доступна вся информация типа, поэтому sizeof оценивается тогда и там во время компиляции и значение заменяется. Как уже упоминалось в @pmg «Из стандарта C99» до. – rakesh 23 November 2011 в 11:51
  • 6
    -1, так как это противоречит принятому (и правильному) ответу и не цитирует стандарт. – sam hocevar 23 November 2011 в 12:36
  • 7
    & lt; sizeof будет происходить во время компиляции & quot; для чего-то, что не является массивом переменной длины – curiousguy 24 November 2011 в 01:49
  • 8
    Хорошая выгода для компиляции временного разрешения оператора sizeof () при работе со строками. Если у вас есть строка, которая инициализируется как строка с кавычками, вместо использования strlen (), где массив символов, содержащий строку, должен быть отсканирован для нуль-терминатора во время выполнения, sizeof (quoted_string) известен во время компиляции, и, следовательно, во время выполнения. Это небольшая вещь, но если вы используете цитированную строку в цикле миллионы и миллионы раз, она существенно влияет на производительность. – user2548100 16 January 2014 в 03:17

Поскольку операнд оператора sizeof не оценивается, вы можете сделать это:

int f(); //no definition, which means we cannot call it

int main(void) {
        printf("%d", sizeof(f()) );  //no linker error
        return 0;
}

Демо-версия онлайн: http://ideone.com/S8e2Y

То есть вам не нужно определять функцию f, если она используется только в sizeof. Этот метод в основном используется в метапрограммировании шаблонов C ++, так как даже в C ++ операнд sizeof не оценивается.

Почему это работает? Он работает, потому что оператор sizeof не работает с значением , вместо этого он работает с типом выражения. Поэтому, когда вы пишете sizeof(f()), он работает с типом выражения f(), и это не что иное, как возвращаемый тип функции f. Тип возврата всегда один и тот же, независимо от того, какое значение возвратит функция, если оно действительно выполняется.

В C ++ вы можете даже это:

struct A
{
  A(); //no definition, which means we cannot create instance!
  int f(); //no definition, which means we cannot call it
};

int main() {
        std::cout << sizeof(A().f())<< std::endl;
        return 0;
}

Однако похоже, в sizeof я сначала создаю экземпляр A, записывая A(), а затем вызывая функцию f в экземпляре, написав A().f(), но такого не происходит.

Демо: http://ideone.com/egPMi

Вот еще одна тема, которая объясняет некоторые другие интересные свойства sizeof:

10
ответ дан Community 21 August 2018 в 14:08
поделиться

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

(sizeof x)  //this also works
33
ответ дан hugomg 21 August 2018 в 14:08
поделиться
  • 1
    будет sizeof ((i ++)) работать? – Gaotter 22 November 2011 в 15:56
  • 2
    @Gaotter: да, дополнительные круглые скобки игнорируются: codepad.org/fhdjYhzV – André Paramés 22 November 2011 в 17:19
  • 3
    Но как это ответ на вопрос? – Sebastian Mach 23 November 2011 в 14:15
  • 4
    @phresnel: Это просто, чтобы было ясно, что sizeof является «странным». и не подчиняется правилам нормальных функций. Я отредактировал сообщение в любом случае, чтобы удалить возможную путаницу с обычными операторами времени выполнения, такими как (+) и (-) – hugomg 23 November 2011 в 14:25

sizeof(foo) действительно пытается обнаружить размер выражения во время компиляции:

6.5.3.4:

Оператор sizeof дает размер (в байтах) ) его операнда, который может быть выражением или заключенным в скобки именем типа. Размер определяется по типу операнда. Результат - целое число. Если тип операнда - тип массива переменной длины, то операнд оценивается; в противном случае операнд не оценивается, а результат является целочисленной константой.

Короче: массивы переменной длины, выполняемые во время выполнения. (Примечание: Массивы переменной длины - это определенная функция - не массивы, выделенные с помощью malloc(3).) В противном случае вычисляется только тип выражения и что при компиляции время.

46
ответ дан sarnold 21 August 2018 в 14:08
поделиться
Оператор

sizeof() дает размер только типа данных, он не оценивает внутренние элементы.

18
ответ дан Shafik Yaghmour 21 August 2018 в 14:08
поделиться
  • 1
    Здесь важно помнить, что большую часть времени sizeof фактически является макросом - он не создает код, а предварительно вычисляет ожидаемое значение и вносит его прямо в код. Обратите внимание, что это было поведение only до C99, поскольку VBAs не существовало (я бы никогда не слышал о них до этого ответа, верьте или нет!) – Corley Brigman 24 February 2014 в 20:17
  • 2
    Каким образом sizeof (char[x++]); использует значение x для чего-либо иного, кроме определения значения выражения x++ и нового значения для x, оба из которых являются нормальными с этим оператором? – supercat 24 February 2014 в 21:21
  • 3
    @alk ... err, да, я имел в виду «VLA», конечно :) Shafik - почему они будут оцениваться во время выполнения? как я уже сказал, я никогда не видел VLA, но типы тех, которые известны во время компиляции, не так ли? – Corley Brigman 24 February 2014 в 22:45
  • 4
    @CorleyBrigman - быстрый ответ будет b / c, так говорит стандарт, но причина в том, что b / c мы не знаем размер массива во время компиляции, поэтому нам нужно оценить выражение во время выполнения. VLA - интересная тема, здесь две записи, которые у меня есть здесь здесь и здесь . – Shafik Yaghmour 25 February 2014 в 00:46
  • 5
    @Shafik - ах, хорошо, я думаю, что моя путаница была я не понимал, что char[x++] - VLA. он выглядит эффектно, как char* для моих незнакомых глаз. – Corley Brigman 25 February 2014 в 20:30
177
ответ дан codaddict 1 November 2018 в 08:10
поделиться
18
ответ дан Shafik Yaghmour 1 November 2018 в 08:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: