C-указатель арифметики

С учетом этого кода:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

Что такое q - p и как?

Ответы

Ответ 1

На самом деле undefined, в соответствии со стандартом. Арифметика указателя не гарантируется работать, если указатели не указывают либо на элемент в, либо за пределы того же массива.

Соответствующий раздел стандарта - 6.5.6: 9 (n1362 черновик c1x, но это не изменилось с c99), который гласит:

Когда два указателя вычитаются, оба указывают на элементы одного и того же объекта массива, или один за последним элементом объекта массива; в результате возникает разница индексы двух элементов массива.

Скорее всего, вы получите 250, если ваш тип данных int - 4 байта, но нет гарантии. Поведение Undefined (в отличие от поведения, определенного реализацией) означает только undefined. Все может произойти, вплоть до полного уничтожения значительной части пространства-времени.

Курс переподготовки:

  • Определенное поведение - это то, что предусмотрено стандартом. Реализации должны делать это, чтобы быть совместимыми.
  • Поведение, определяемое реализацией, остается до реализации, но оно должно четко документировать это поведение. Используйте это, если вы не слишком заботитесь о переносимости.
  • Undefined поведение означает, что все может случиться. Никогда не делай этого!

Ответ 2

q - p равно 250.

2000 - 1000 = 1000
1000 / sizeof(int) = 250

арифметика указателя, если sizeof (int) равен 4.


Редактировать: ОК, чтобы уточнить. В C, когда два указателя имеют один и тот же тип, тогда разница между ними определяется количеством вещей между указанным типом между ними. Например,
struct foo { int ar[1000]; } big[10];
char small[10];

struct foo *fs, *fe;
char *ss, *se;

fs = &big[0]; fe = &big[9];
ss = &small[0]; se = &small[9];

fe - fs == se - ss;

То есть разница между двумя указателями в этом случае - это количество элементов массива между ними. В этом случае это 0, 1,... 8 или 9 элементов.

Ответ 3

q-p должен возвращать количество шагов с шагом, которое вы должны сделать, чтобы перейти от p в q. Это 1000 / sizeof(int) и равно 250. Помните, что q++ действительно перейдет к следующему элементу типа int, а не к середине его, поэтому он должен добавить 4 к фактическому значению указателя. Следовательно, результат.

Ответ 4

Ответ: q-p будет 250, если вы на машине, где int - 4 байта.

Вычисление:

q - p = 1000 1000/4 (размер int) = 250

Идея этого:

Идея арифметики указателя заключается в том, что если у вас есть указатель int на 1000 и указатель int на 2000, и попросите разницу, вы не спрашиваете, что 2000 -1000. Что вы спрашиваете, , сколько int можно установить между ними.

Это очень удобно для всех видов операций, например:

int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.

Это особенно полезно при работе с массивами. Массив ints (определенный int arr[10]) в основном обрабатывается как указатель. Когда вы пишете arr[5], компилятор переводит его на *(arr + 5), т.е. Добавляет 5 к указателю int, называемому arr, и получает значение по этому адресу.

Причина, по которой это работает, заключается в том, что arr + 5 означает не означает "добавить 5 к значению arr", это означает "добавить все, что является neceassary, к значению arr для перехода вперед 5 int s" или, точнее, "добавить 5 * sizeof(int) к значению arr"

Ответ 5

Поскольку p указывает на int и, следовательно, q, q-p будет 1000.