Как массив C является «именованной переменной в своем собственном праве»? - PullRequest
0 голосов
/ 10 февраля 2019

На странице 103 в книге «Программирование на Эксперт C: секреты Deep C» Питера Ван Дер Линдена есть таблица с разницей между массивами и указателями.

Один выпуск Iне совсем понимаю - прямая кавычка:

Указатель: Обычно указывает на анонимные данные

Массив: Является именованной переменной всвое право

Что это значит?Поскольку вы можете сделать следующее:

#include <stdio.h>
#include <stdlib.h>

int main(void){
  int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  int *y = malloc(9*sizeof(int));
  printf("sizeof(x) == %zu\n", sizeof(x));
  printf("&(x[2]) = %p\n", (void*)&(x[2]));
  printf("sizeof(y) == %zu\n", sizeof(y));
  printf("&(y[2]) = %p\n", (void*)&(y[2]));
  return 0;
}

Вывод:

sizeof(x) == 36
&(x[2]) = 0x7fffffffe5f8
sizeof(y) == 8
&(y[2]) = 0x800e18008

Я не вижу, как y меньше именованной переменной, чем x.

Ответы [ 4 ]

0 голосов
/ 19 марта 2019

Мы в основном догадываемся, что имел в виду кто-то другой.Но вот мое лучшее предположение.

  int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  int *y = malloc(9*sizeof(int));

x - это имя массива.

y - это имя указателя.Массив, на который он указывает, не имеет имени.

0 голосов
/ 10 февраля 2019

Я думаю, что автор пытается сказать, что элементы массива образуют именованный "объект" (по определению стандарта C), тогда как элементы указателя часто происходят из неназванного "объекта".".

См. C11 §3.15 для определения объекта и §6.2.4 для информации о продолжительности хранения объекта.

Существует лот дерьматам есть книги по программированию, и C, будучи старым и популярным языком, имеет больше, чем большинство.

0 голосов
/ 10 февраля 2019

На самом деле вы написали два способа объявить массив.Первый, конечно, более условный и простой.Автор пытается сказать нам, что массив является именованной переменной, потому что вам нужна именованная переменная для доступа ко всем элементам массива.Чтобы перейти к следующему элементу и т. Д., Вам нужно разместить индексный номер.Итак, по «адресу» первого элемента, умноженному на порядковый номер, вы попадете на нужный элемент.Если мы проанализируем его, массив [0] указывает на первый элемент и сам по себе является указателем.

Чтобы правильно понять указатель, учтите следующее:

int *y = malloc(sizeof(int));
int x[] = {1,2,3};
y = &x[2]; //points to an anonymous data because pointer "y" doesn't "know" the 
           //variable "x", only it's memory address
y = &x[0]; //points to the first element of x
0 голосов
/ 10 февраля 2019

Автор мог бы быть более понятным здесь, я согласен.Указатель тоже является именованной переменной, но если он указывает на массив, он не имеет никакой информации о длине массива.На самом деле, он не знает, что он указывает на массив.Синтаксис p[100] действителен (хотя и не определен), даже если p был назначен адрес одного int или другого типа данных.

Именно поэтому, когда массив передается в качестве аргумента дляфункция, это либо:

  • Сопровождается параметром "length", который доверяет вызывающему коду для правильной его передачи
  • Завершается значением часового значения (как нулевой терминатор для строк)

Чтобы более четко продемонстрировать это различие, попробуйте следующее:

int arr[3] = { 1,2,3 };
int *ptr;
ptr = &arr;

Я получаю следующее предупреждение компиляции:

'=': 'int *' differs in levels of indirection from 'int (*)[3]'

Но, если вы измените ptr для указания на первый элемент arr (что происходит, когда arr распадается на указатель), проблем нет:

ptr = &arr[0];
...