Вопрос1) Я думал, что он нужен для того, что в 32-битных сис-мах может не хватитить 1ого слова (если оперативы> 2^32/8/1024/1024 (т. е. 512мбайт) ) для записи адреса. Но это:
main ()
{
double a; float b; int c; char d;
printf (" %d\n %d\n %d\n %d", sizeof &a, sizeof &b, sizeof &c, sizeof &d);
}
Выдает, что адрес = 4байтам. Если это так, то почему бы &count не возвращал бы int? Но с другой стороны, как он может возвращать int, если на компе > 512Мбайт оперативки? В общем, зачем нужно было создание отдельного типа "указатель"?
Вопрос2) Как происходит процесс обявления переменной? Ведь по индее, например, для int'a должно быть выделено 4байта для самого числа + память для хранения адреса. Вообще адрес переменной хранится в памяти или блин, как это все проиходит?
Другие языки программирования и технологии
Зачем в С/C++ создан отдельный тип "указатель"
Да так и происходит, объявляем переменную типа int, под неё выделяется память 4 байта по конкретному адресу и этот адрес операционная система хранит в указателе, который нам не известен, но память занимает. Скрыт он для того, чтобы им нельзя было манипулировать.
Однако ничто нам не мешает создать свой собственный указатель, и с помощью операции взятия адреса занести в него адрес переменной. Таким указателем удобно манипулировать, Например:
А также можно доказать, что указатель это переменная и у неё есть адрес. Для этого используем указатель типа void...
Однако ничто нам не мешает создать свой собственный указатель, и с помощью операции взятия адреса занести в него адрес переменной. Таким указателем удобно манипулировать, Например:

А также можно доказать, что указатель это переменная и у неё есть адрес. Для этого используем указатель типа void...

Указатель - это переменная для хранения адреса. Когда мы объявляем
int a компилятор разместит ячейку для хранения целого числа. Если же объявлено int *a, то память выделяется не для хранения целого числа, а для хранения адреса на участок памяти, в котором хранится целое число. Который еще надо выделить.
"На пальцах" это можно объяснить так: представьте, что у вас есть шкаф со множеством ящичков. Вы можете взять предмет (или несколько предметов) , например горошины и положить их в один из ящиков. Это случай выделения ячеки под значение. А тепрь представим, что к вам привезли слона. Ящика для него нет, поэтому слона помещаем в соседнюю комнату, а чтобы не забыть об этом в одни из ящиков помещаем записку - слон в комнате №2. Этот ящик и будет аналогией переменной типа "указатель на слона". Такое представление достаточно для большинства практических целей.
Указатели используются для разных целей. Например, при передаче параметров. Можно передать значение (т. е. копию содержимого определенного участка памяти) , а можно - только указатель на этот участок. Так же указатели не заменимы в случае, когда на момент компиляции программы неизвестно сколько памяти будут занимать данные. Например, пишем программу, обрабатывающую массив чисел, длинна которого задается пользователем. Можно, конечно, объявить статический массив максимальной длины, но это не рационалино, особенно если в большинстве случаев массив будет в 10 элементов. Вот тут нам и помогут указатели - мы пишем программу, в которой вместо указания конкретной ячеки памяти используется указатель на начало блока и смещение. В начале программы получаем число-размерность массива, выделяем блок памяти необходимого размера и его адрес помещаем в переменную-указатель. Можно привести еще массу примеров, для случаев, когда указатели не просто удобны, а просто необходимы.
Ответ на второй вопрос зависит от используемого компилятора и ряда доп. условий. Там ситуация несколько сложнее, чем в "практическом взгляде" на указатель, поскольку, выделение памяти под переменные может происходить разными способами или (в случае регистровых переменных) вообще не происходить. А физически указатель может быть не просто адресом ячейки памяти, а более сложной вещью - "виртуальным" адресом в пространстве адресов менеджера памяти. Впрочем, как правило, нет необходимости забивать себе голову этими подробностями, достаточно представлять себе значение указателя как адрес ячейки памяти.
int a компилятор разместит ячейку для хранения целого числа. Если же объявлено int *a, то память выделяется не для хранения целого числа, а для хранения адреса на участок памяти, в котором хранится целое число. Который еще надо выделить.
"На пальцах" это можно объяснить так: представьте, что у вас есть шкаф со множеством ящичков. Вы можете взять предмет (или несколько предметов) , например горошины и положить их в один из ящиков. Это случай выделения ячеки под значение. А тепрь представим, что к вам привезли слона. Ящика для него нет, поэтому слона помещаем в соседнюю комнату, а чтобы не забыть об этом в одни из ящиков помещаем записку - слон в комнате №2. Этот ящик и будет аналогией переменной типа "указатель на слона". Такое представление достаточно для большинства практических целей.
Указатели используются для разных целей. Например, при передаче параметров. Можно передать значение (т. е. копию содержимого определенного участка памяти) , а можно - только указатель на этот участок. Так же указатели не заменимы в случае, когда на момент компиляции программы неизвестно сколько памяти будут занимать данные. Например, пишем программу, обрабатывающую массив чисел, длинна которого задается пользователем. Можно, конечно, объявить статический массив максимальной длины, но это не рационалино, особенно если в большинстве случаев массив будет в 10 элементов. Вот тут нам и помогут указатели - мы пишем программу, в которой вместо указания конкретной ячеки памяти используется указатель на начало блока и смещение. В начале программы получаем число-размерность массива, выделяем блок памяти необходимого размера и его адрес помещаем в переменную-указатель. Можно привести еще массу примеров, для случаев, когда указатели не просто удобны, а просто необходимы.
Ответ на второй вопрос зависит от используемого компилятора и ряда доп. условий. Там ситуация несколько сложнее, чем в "практическом взгляде" на указатель, поскольку, выделение памяти под переменные может происходить разными способами или (в случае регистровых переменных) вообще не происходить. А физически указатель может быть не просто адресом ячейки памяти, а более сложной вещью - "виртуальным" адресом в пространстве адресов менеджера памяти. Впрочем, как правило, нет необходимости забивать себе голову этими подробностями, достаточно представлять себе значение указателя как адрес ячейки памяти.
Понимание, действительно пока отсутствует!
В данных ЭВМ всё построено на двоичной системе.
Упрощённо есть процессор и есть ОЗУ связанные двумя шинами: данных и адреса.
Дальше всё упирается в размер ячеек как в процессоре, так и адресуемых в ОЗУ
Адреса ячеек - это двоичное значение, занимающее несколько разрядов
Для 32-битной адресации можно адресовать только к 4Гигаячейкам памяти. Размер ячеек может быть разный: 8 бит, 16 бит, 32 бита, 64 бита и т. п.
Если регистры процессора тоже 32-разрядные, то в них можно хранить адреса этих ячеек
Если ОЗУ имеет бОльший размер в ячейках, то требуется переход к расширенной адресации, и для хранения адресов требуются ячейки бОльшей разрядности.
Так как 4Гига уже становятся малым размером, а переход к 64-разрядным процессорам дорог (сейчас в основном из-за ПО) поэтому для 32-битных процессоров придумали 64-х битную совместимость, добавив в процессор 64-битные регистры и АЛУ для их обработки.
А указатели - это переменные, хранящие адрес в качестве значения. В широко применяемом Вами процессоре некоторые регистры используются для косвенной адресации, особенно удобной при автоинкременте в циклах, чтобы не занимать под инкремент адреса отдельную команду. Адреса инкрементируются в отдельном юните процессора, а значение по их адресам участвуют в работе с другим юнитом процессора.
В общем читайте буквари, там всё написано!
В данных ЭВМ всё построено на двоичной системе.
Упрощённо есть процессор и есть ОЗУ связанные двумя шинами: данных и адреса.
Дальше всё упирается в размер ячеек как в процессоре, так и адресуемых в ОЗУ
Адреса ячеек - это двоичное значение, занимающее несколько разрядов
Для 32-битной адресации можно адресовать только к 4Гигаячейкам памяти. Размер ячеек может быть разный: 8 бит, 16 бит, 32 бита, 64 бита и т. п.
Если регистры процессора тоже 32-разрядные, то в них можно хранить адреса этих ячеек
Если ОЗУ имеет бОльший размер в ячейках, то требуется переход к расширенной адресации, и для хранения адресов требуются ячейки бОльшей разрядности.
Так как 4Гига уже становятся малым размером, а переход к 64-разрядным процессорам дорог (сейчас в основном из-за ПО) поэтому для 32-битных процессоров придумали 64-х битную совместимость, добавив в процессор 64-битные регистры и АЛУ для их обработки.
А указатели - это переменные, хранящие адрес в качестве значения. В широко применяемом Вами процессоре некоторые регистры используются для косвенной адресации, особенно удобной при автоинкременте в циклах, чтобы не занимать под инкремент адреса отдельную команду. Адреса инкрементируются в отдельном юните процессора, а значение по их адресам участвуют в работе с другим юнитом процессора.
В общем читайте буквари, там всё написано!
Указатель возник исторически. С вышел из тех времен, когда работали с адресами и машинным представлением чисел, они гораздо ближе к машинным командам. С сначала был просто стенографическим вариантом Ассемблера.
«Нужен был язык, способный обойти некоторые жесткие правила, встроенные в большинство языков высокого уровня и обеспечивающие их надежность. Нужен был такой язык, который позволил бы делать то, что до него можно было реализовать только на ассемблере или на уровне машинного кода. » (Питер Мойлан)
P.S. "Ну я измерил размеры адресов. " На своем компьютере и компиляторе. На других они могут быть другими и даже, как я писал, состоять из двух разных чисел.
А для int не надо выделять память для хранения адреса. Зачем? Адрес обычного int уже записан в коде самой программы. Впрочем, операционная система при размещении программы в памяти его автоматически корректирует.
«Нужен был язык, способный обойти некоторые жесткие правила, встроенные в большинство языков высокого уровня и обеспечивающие их надежность. Нужен был такой язык, который позволил бы делать то, что до него можно было реализовать только на ассемблере или на уровне машинного кода. » (Питер Мойлан)
P.S. "Ну я измерил размеры адресов. " На своем компьютере и компиляторе. На других они могут быть другими и даже, как я писал, состоять из двух разных чисел.
А для int не надо выделять память для хранения адреса. Зачем? Адрес обычного int уже записан в коде самой программы. Впрочем, операционная система при размещении программы в памяти его автоматически корректирует.
я что-то не понимаю?
где тут указатель в коде-то?
действительное число с двойной точностью, действительное число, целое число, символьная переменная
а по второму вопросу - сдаётся мне, где-то у тебя недопонимание, перечитай основы адресации
где тут указатель в коде-то?
действительное число с двойной точностью, действительное число, целое число, символьная переменная
а по второму вопросу - сдаётся мне, где-то у тебя недопонимание, перечитай основы адресации
1)На 32 битной системе не обратишься к памяти выше 4гб, тк указатели размером 2^32. Это упрощенно говоря, а на самом деле там еще прибавляется к адресации селектор текущего сегмента и теневой регистр. Проще говоря для обращения к любой ячейки памяти используется 32битное значение, и не важно что хранится в этой ячейке. А в C указатели обычно применяются для работы с массивами или для передачи параметров в функцию, так чтобы функция могла возвратить в них что-нибудь. Т. е. передается указатель, а функция по этому указателю что-либо туда пишет
2)На этапе компиляции для глобальных переменных 4байт под int выделяется в самом exe-файле, и потом при отображении exe в память, место под int соответственно тоже там оказывается. Для локальных же переменных место выделяется в стеке. На этапе компиляции рассчитывается на сколько сдвигать вершину стека, чтобы получить необходимый размер памяти
2)На этапе компиляции для глобальных переменных 4байт под int выделяется в самом exe-файле, и потом при отображении exe в память, место под int соответственно тоже там оказывается. Для локальных же переменных место выделяется в стеке. На этапе компиляции рассчитывается на сколько сдвигать вершину стека, чтобы получить необходимый размер памяти
Есть всего 4 типа данных:
1. байт
2. слово (2 байта)
3. двойное слово (4 байта)
4. и четверное слово (8 байт)
Все остальные - эти же 4 типа, только другими словами.
1. байт
2. слово (2 байта)
3. двойное слово (4 байта)
4. и четверное слово (8 байт)
Все остальные - эти же 4 типа, только другими словами.
Похожие вопросы
- Как на C++ создать массив типа int из стольких элиментов, что бы значение бралось из перемнно count ?
- C++ непонимаю что такое указатель?
- Создать класс типа круг. C++
- Учу C++! Уже знаю: типы данных, циклы. условия, привидения и т. д учу 5дней. вот программа! Как норм за 5 дней?
- [C/C++] Oбъявление переменной типа структуры в этой же структуре
- Подскажите на языке c++ создал новый проект выбрал при создании windows applikation, Создал меню, в как???
- C++ Про выбор типа данных. Int, char и т. д.
- Как в C# создать круг с осями координат , и потом с помощью формулы линией изобразить угол?
- с помощью какого движка можна создать видеопортал типа youtube, где видео храниться в виде ссылок с youtube
- Помогите решить задачу: C# Создать рандомную матрицу nxn (выполнено) после чего сложить данные выделенные элементы: