LINUX.ORG.RU

Снова про указатель

 


0

1

Здравствуйте.

Помогите понять. Я хочу объявить массив указателей и потом присвоить этим указателям ареса других массивов...


uint8_t *globalptr[2]; // глобальный

int main()  
{ 
    uint8_t array_1[16];
    uint8_t array_2[16];
    
    globalptr[0] = array_1;
    globalptr[1] = array_2;
    ...

Всё это работает.

globalptr - хранит адреса массивов. Но ведь он объявлен как uint8_t, как туда влезают ареса.

Или всё это просто не правильно и у меня вылезает за границы? Однако valgrind ничего не говорит.

Помогите, а то запутался что-то.



Последнее исправление: stD (всего исправлений: 1)

Ответ на: комментарий от Harald

Но ведь uint8_t *globalptr[2]; должен хранить адреса массивов (array_1, array_2). То есть 32-х битные числа. Как же они помещаются в uint8_t?

stD
() автор топика
Ответ на: комментарий от stD

Чёта я не догоняю... Троллишь?
Если нет - арихметика! Перепрачесть!
Магия - pointer. Перепрачесть!

Deleted
()
Ответ на: комментарий от stD
uint8_t* globalptr[2]; // глобальный

а так понятнее? Запись эквивалентна

Harald ★★★★★
()

Размер типа и размер указателя на тип это не одно и тоже. Указатель на char * больше чем размер типа char. Так что всё нормально.

anonymous
()
Ответ на: комментарий от anonymous

Ну что за Аноны пошли...
p.s. Оно, конечно, похрен, но в коде ашыбка :) У миня пишет, нема имени ptr_global.

Deleted
()
Ответ на: комментарий от anonymous

Указатель на char * больше чем размер типа char

Тогда я так спрошу:

Какой размер ячейки у - у нулевой ячейки globalptr (globalptr[0]) ?

stD
() автор топика
Ответ на: комментарий от Deleted

А то регистранты лучше, какая ошибка окстись там даже main функция без закрытой скобки с ретурном, как ты вообще скомпилировал, но раз ты добавил скобочку то логично же он не только её опустил но и объявление переменной, да и код тут не нужен со слов всё понятно :)

anonymous
()
Ответ на: комментарий от stD

Какой размер ячейки у - у нулевой ячейки globalptr (globalptr[0]) ?

зависит от системы, на x86 32 бит, на amd64 - 64

Harald ★★★★★
()
Ответ на: комментарий от stD

https://prog-cpp.ru/c-pointers/

Зырь туды:«Каждая переменная в памяти имеет свой адрес — номер первой ячейки, где она расположена, а также свое значение. Указатель — это тоже переменная, которая размещается в памяти. Она тоже имеет адрес, а ее значение является адресом некоторой другой переменной. Переменная, объявленная как указатель, занимает 4 байта в оперативной памяти (в случае 32-битной версии компилятора).»

В твоём случае ты можешь вывести размер указателя через printf... Если совсем припечёт. Google научит, как.

Deleted
()
Ответ на: комментарий от stD

Есть такая штука sizeof() называется она тебе скажет какой размер у чего угодно. Запусти да глянь.

anonymous
()
Ответ на: комментарий от stD
printf("addres %p, size=%d",globalptr[0],sizeof(globalptr[0]));
anonymous
()
Ответ на: комментарий от Deleted

Спасибо.

Поясните если не затруднит, почему в большинстве примеров, всегда пишут:

int *globalptr[2];

То есть int *globalptr[2]; и uint8_t *globalptr[2]; это одно и то же?

stD
() автор топика
Ответ на: комментарий от Deleted

Да я не про размерность спрашивал. Блин я не знаю как правильно вопрос сформулировать...

Попробую так:

Если я объявляю массив...

uint8_t globalptr[2];

Тогда ячейки (globalptr[0] и globalptr[1]) будут размером по 8 бит.

А если я объявляю массив указателей...

uint8_t *globalptr[2];

Тогда ячейки будут какого размера?

stD
() автор топика
Ответ на: комментарий от stD

А что мешает посмотреть? Анон выше типо дал рецепт... Я бы внимательно, с утреца, кхм, перечитал главу. Если не троллишь.

Deleted
()
Последнее исправление: kaban_lyalya (всего исправлений: 2)
Ответ на: комментарий от Deleted

Показывает 8.

Но ведь в ней должен хранится адрес указателя...

uint8_t array_1[16]; ...

globalptr[0] = array_1;

Или я всё вообще не правильно понимаю?

stD
() автор топика
Ответ на: комментарий от stD

размер указателя на x64 - 8 байт... поэтому в указатель влезает любой адрес на этой машине... не важно, будь это int* ptr, long* ptr - все равно sizeof(ptr) = 8;

xperious ★★
()
Ответ на: комментарий от stD

Тогда ячейки будут какого размера?

На разных платформах по разному, в принципе касаемо указателей по началу тебя это колыхать не должно и я повторяюсь глянь размеры через sizeof(). И ещё касательно указателей, я подозреваю ты думаешь что если к примеру указатель имеет адрес типа 123 (для простоты в десятичной системе и коротко) и к нему добавить 1 будет 124? )))))))))))))))))))

anonymous
()
Ответ на: комментарий от xperious

Я всё понял. Я идиот, я перепутал биты с байтами.

stD
() автор топика
Ответ на: комментарий от Deleted

И не говорика, всю малину обломал!

anonymous
()
Ответ на: комментарий от Deleted

Получается, что не имеет значения что писать?...

uint8_t *globalptr[2];

или

int *globalptr[2];

Ну вот зачем? Нас троллили, мы резво отбивались...

Извиняюсь что разочаровал.

stD
() автор топика
Ответ на: комментарий от stD

uint8_t дабавили в стандарт. Раньше этаго не было. Я же тебе привёл ссылки. На данной платформе, возможно, ты не заметишь разницы, но сам понимаешь...

Deleted
()
Ответ на: комментарий от Deleted

Таки тролль ;)

Эх, если бы.

...

Разрешите последний вопрос, на понимание.

То есть, когда я говорю в программе «создай мне массив указателей»...

uint8_t *ptr_global[2];

...то будет создан массив, ячейка (ptr_global[0]) которого будет равна размеру указателя для данной системы.

stD
() автор топика
Ответ на: комментарий от stD

Бляяяяяяяяяяяяяяяяя

Есть фундаментальные типы char , short, (singned,unsigned,long,long long) int, float, double и на каждой платформе у них Раааааааааааааазный размер, но размер не менее чем описан в стандарте, всё остальное это typedef char uint8_t и так далее. На всё это дерьмо есть указатели размер укатателей ОДИН И ТОТЖЕ внутри платформы для любых типов, НО! int * и long long int * разные ибо есть аддресная арифметика тоесть если к адресу добавить ОДЫН ЕДЕНИЦА то адрес станет больше не на ОДЫН ЕДЕНИЦА а на размер типа на который он ссылается. K&R бери и перечитывай.

anonymous
()
Ответ на: комментарий от anonymous

НО! int * и long long int * разные ибо есть аддресная арифметика тоесть если к адресу добавить ОДЫН ЕДЕНИЦА то адрес станет больше не на ОДЫН ЕДЕНИЦА а на размер типа на который он ссылается.

Спасибо. Это всё проясняет.

stD
() автор топика
Ответ на: комментарий от stD

То есть, в данном случае...

uint8_t *ptr_global[2];

...тип uint8_t влияет только на аддресную арифметику. Да?

stD
() автор топика
Ответ на: комментарий от anonymous

Я не ругаюсь,но правда лучше не торопять, а лучше проводя эксперименты с кодом дойти самому до понимания, порой вещи неочевидны до целчка в голове и восклика Эврика! с повышением дофамина и серотонина в голове. Я серьёзно, можно начать с википедии и просмотра заголовочных файлов стандартной библиотеки. Главное постарайся осознать самостоятельно, а то от разжёванных данных ты можешь словить ложное осознание что ты понял, но это булет не так, узнать и запомнить это одно, понять это другое и второе гораздо важнее

anonymous
()
Ответ на: комментарий от Deleted

Спасибо. И спасибо за ссылку. И спасибо всем. Вопрос закрыт.

stD
() автор топика
Ответ на: комментарий от stD

Да, и когда ты пишешь uint8_t * ты говоришь компилятору, тут мне нужен указатель на целочисленную переменную размером не менее 8 бит и не ниже нуля. Ты ведь понимаешь что uint8_t это unsigned int 8 bit type расшифровывается и где то в потрохах заголовочных файлов ссылается на один из фундаментальных типов. И нужно это для того что бы код мог работать и на микроконтролёре восьмибитном и на ПК домашнем одинаково.

Всё, капча меня доканала, я спать пошёл, всем доброй ночи.

anonymous
()
Ответ на: комментарий от stD

Ащето важно, где то может быть uint8_t это не char, a unsigned int )))))))))))). Важен не точный размер, а размер не меньше

Нельзя делать так


int  num =  322;
char ch  = '3';

int  * pnum = #
char * pch  = &ch;

pnum = pch;

Нужно явно приводить тип

pnum = (int*)pch;

Пример дурацкий, но суть должна быть ясна.

anonymous
()
Ответ на: комментарий от anonymous

Наверно это уже не важно, но всё же поясню причину по которой создал топик.

Создавая обычный массив...

 
char globalptr[2];


...ячейка будет равна 1 байт.

Вот меня и замкнуло, как же так, создавая массив указателей, я указываю тип uint8_t, значит размер ячейки будет 8 бит. Проверил sizeofом, в ответ получил 8!!! Подумал, да действительно, а как же туда поместится адрес указателя. Ну а дальше понеслось...
stD
() автор топика
Ответ на: комментарий от stD

Блин, ну почему нельзя отредактировать сообщение.

stD
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.