Порядок оценки для чайников

Я не могу понять стратегию оценки, независимо от того, сколько я читаю темы. Можете ли вы объяснить мне три приказа об оценке на примере? Я пишу код ниже. Можете ли вы объяснить вызов по необходимости (ленивая оценка), вызов по имени (нормальная оценка заказа), вызов по ссылке, используя код ниже. Вы также можете объяснить их своим примером. Все, что я хочу, это понять их, но я просто не могу понять.

int a[4] = {10,20,30,40};
int i = 0;
int *p;
void test(int x, int y, int z)
{
    p = (int *)malloc(sizeof(int));
    *p=x;
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
    x++; y++; z++;
    p = &z;
    printf("%d %d %d\n",x,y,z);
}
main()
{
    test(i,a[0],a[i]);
    printf("%d %d %d %d %d\n", a[0],a[1],a[2],a[3],*p);
}

Заранее спасибо.

}

1 ответ

Решение

Здесь нет лени, потому что все затронутое передается по значению, и глобальный указатель никогда не разыменовывается до тех пор, пока это не станет неопределенным поведением (указатель на локальную переменную функции, которая уже вернулась).

Поведение программы со значениями соответствующих выражений, которые будут отображаться в списке наблюдения отладчика. Обратите внимание, что *p это выражение, а не переменная: отладчик будет оценивать это лениво, но это не то, что на самом деле в памяти.

  1. Call to test () оценивает выражения i, a[0] а также a[i] в 0, 10 а также 10 соответственно.
  2. тест (0, 10, 10) начинается -> {x, y, z, p, *p} = {0, 10, 10, (не инициализирован), (недействителен)}
  3. p = (int *)malloc(sizeof(int)); -> {x, y, z, p, *p} = {0, 10, 10, (где-то в куче), (неинициализировано)}
  4. *p=x; -> {x, y, z, p, *p} = {0, 10, 10, (где-то в куче), 0}
  5. x++; y++; z++; -> {x, y, z, p, *p} = {1, 11, 11, (где-то в куче), 0}
  6. p = &z; -> {x, y, z, p, *p} = {1, 11, 11, &z, 11} (утечка памяти, адрес памяти malloc'd "забыт" без освобождения)
  7. printf("%d %d %d\n",x,y,z); дисплеи 1 11 11
  8. x++; y++; z++; -> {x, y, z, p, *p} = {2, 12, 12, &z, 12}
  9. p = &z; Без изменений, p уже указывал на z.
  10. printf("%d %d %d\n",x,y,z); дисплеи 2 12 12
  11. Функция возвращается. p теперь висячий указатель! Когда вы разыменовываете это, может случиться что угодно.
  12. Большой printf(): пятое число не определено (приложение может даже аварийно завершить работу, прежде чем будет вызвана функция), но, возможно, это будет 12, если звезды правильные. В этом случае он отображает 10 20 30 40 12

На самом деле, указатель на самом деле не используется для демонстрации того, как работают указатели: это своего рода большой потерянный потенциал. Что касается указателей, это плохой пример кода.

Другие вопросы по тегам