Почему у нас есть указатели кроме пустоты

Я знаю, что у нас есть различные указатели как int, float, и char. A void указатель является единственным указателем, который может содержать всех других.

Другие указатели существуют только, чтобы гибкость сделала адресную арифметику с указателями?

Есть ли любая другая причина это указатели кроме void присутствуют на языке C?

27
задан Vijay 4 February 2010 в 14:39
поделиться

10 ответов

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

20
ответ дан 28 November 2019 в 05:03
поделиться

Есть ли еще какая-то причина того, что указатели, отличные от void, присутствуют в языке C?

Это отличный способ свободно обрабатывать фрагменты памяти. :)

0
ответ дан 28 November 2019 в 05:03
поделиться

Очень просто:

void* p;
*p; // compile error!

Или, говоря словами; указатель void не может быть разыменован.

Возможно, вам следует переименовать вопрос, почему у нас есть указатели, или, скорее, их нет, и просто поискать этот вопрос на SO.

4
ответ дан 28 November 2019 в 05:03
поделиться

При использовании указателя на float или int (например) компилятор знает, сколько байт он должен взять из памяти (sizeof(int) для int* например).

С пустым значением нужно будет каждый раз сообщать компилятору, сколько байт он должен взять (например, записывая (int*)some_void_ptr).

Но это большое упрощение.

3
ответ дан 28 November 2019 в 05:03
поделиться

Компилятору необходимо знать указанные типы, иначе любой код не будет работать. Примите во внимание следующее:

*a = *b + *c;    // Should this add char? int? float?
s_ptr->x = 0;    // How does the compiler know anything about the structure s_ptr points to?
a[5] = 0;        // How far is a[5] from a[0]?

Отсутствие типов для указателей было бы похоже на отсутствие типов для чего-либо. Компилятор был бы полностью потерян. Короче говоря, C и C ++ строго типизированы, и это переносится на указатели по довольно очевидным причинам.

14
ответ дан 28 November 2019 в 05:03
поделиться
int o = 12;
void *i = &o;

Как бы вы получили доступ к int, на которую указывает i, если бы существовали только указатели на пустоты и не было int*. Возможно, вы знаете, что на вашей платформе int - это 4 байта, поэтому вы можете записать в память 4 байта от начала того, на что указывает void*, во временную int, а затем использовать ее. Но это не очень удобно.

Или, учитывая

struct Pair {
   char *first;
   char *second;
};

, насколько полезным будет указатель void для структурирования пары? Скорее всего, вы захотите получить доступ к его первому члену , и это очень много работы, если у вас не будет указателя на пару структур.

8
ответ дан 28 November 2019 в 05:03
поделиться

При итерации по блоку памяти, на который указывает указатель, необходимо знать размер типа данных, который хранится в памяти. Скажем, у вас есть два указателя, char charptr и int intptr, оба указывают на память в байте X. charptr + 1 будет указывать на байт X + 1, а intptr + 1 будет указывать на байт X + 4.

Быстрый и грязный фрагмент плохо написанного кода, чтобы проиллюстрировать, что:

#include <stdio.h>

int main()
{
    char * cptr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    short * sptr = (short*)cptr;
    int * iptr = (int*)cptr;
    long long * lptr = (long long*)cptr;

    printf ("CHAR: %d, +1: %d\n",cptr,cptr+1);
    printf ("SHORT: %d, +1: %d\n",sptr,sptr+1);
    printf ("INT: %d, +1: %d\n",iptr,iptr+1);
    printf ("LONG LONG: %d, +1: %d\n",lptr,lptr+1);
}

Это должно:

  • генерировать предупреждения о приведении указателей разных размеров (безопасность типов),
  • выводить идентичные числа в первом столбце (все указатели указывают на один и тот же адрес в памяти), но разные числа во 2-м столбце (это базовый адрес + размер типа указателя: 1, 2, 4 и 8 байтов).
0
ответ дан 28 November 2019 в 05:03
поделиться

На самом деле это - "указатель на пустоту", которая должна быть объяснена.

На языках программирования в целом и в C, в частности, нам нравятся типы. Типы являются основной системой поддержки, которая проверяет, делаем ли мы что-то глупое, где "глупый" средства "интерпретировать набор битов для чего-то, что они не". Это возможно к программе без типов, некоторые языки полностью лишены любого вида типа (например, блок или Forth), но это не для слабонервных и, вообще говоря, производительность программиста, кажется, значительно улучшена при помощи типов.

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

"указатель на пустоту" является указателем без типов, который мы используем, когда системе типов C не удается получить то, что мы делаем. Это - признак C, не бывшего способного следовать за сложностью кода, который мы производим (или возможно программист не был достаточно хорош для выражения то, что он делает в рамках ограничений системы типов C). Следовательно, в то время как "пусто *" удобно в некоторых ситуациях, нужно рассматривать его как исключение и стараться избегать его.

2
ответ дан 28 November 2019 в 05:03
поделиться

Тип указателя в C сообщает компилятору, каков размер блока памяти, который нужно прочитать в случае, если вы попытаетесь разыменовать его. Другими словами, при разыменовании указателя int компилятор знает, что после адреса должны быть прочитаны 4 байта. Вот почему разыменование пустого указателя без его приведения к типизированному указателю запрещено - в этом случае компилятор не знает, сколько байтов читать после адреса.

2
ответ дан 28 November 2019 в 05:03
поделиться

Два слова: Тип Безопасность

В Википедии на C есть небольшая лакомый кусочек по типу безопасности (или ее отсутствие), который может пролить свет на вас.

0
ответ дан 28 November 2019 в 05:03
поделиться
Другие вопросы по тегам:

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