Выражение присваивания C в аргументе функции [дубликат]

Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение NullReferenceException.

Пример:

Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.

Вы можно просто избежать этого, проверив, является ли переменная не нулевой:

Person p = null;
if (p!=null)
{
    p.Name = "Harry"; // Not going to run to this point
}

Чтобы полностью понять, почему выбрано исключение NullReferenceException, важно знать разницу между типами значений и ссылочные типы .

Итак, если вы имеете дело со типами значений, NullReferenceExceptions не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!

Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.

Типы ссылок (эти должны быть проверены):

  • динамический
  • объект
  • string

Типы значений (вы можете просто игнорировать эти):

  • Числовые типы
  • Интегральные типы
  • Типы с плавающей запятой
  • decimal
  • bool
  • Пользовательские структуры

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

6 ответов

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

6.5.3.4/2

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

502
ответ дан Nawaz 28 August 2018 в 09:13
поделиться

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

175
ответ дан codaddict 28 August 2018 в 09:13
поделиться

Поскольку операнд оператора 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 28 August 2018 в 09:13
поделиться

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

(sizeof x)  //this also works
33
ответ дан hugomg 28 August 2018 в 09:13
поделиться

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

6.5.3.4:

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

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

46
ответ дан sarnold 28 August 2018 в 09:13
поделиться
Оператор

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

18
ответ дан Shafik Yaghmour 28 August 2018 в 09:13
поделиться
Другие вопросы по тегам:

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