Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.70/40: Рейтинг темы: голосов - 40, средняя оценка - 4.70
Smypir
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 127
1

Указатели СИ

26.05.2010, 19:39. Просмотров 7312. Ответов 14
Метки нет (Все метки)

Вот написал простой код
Код
unsykned int *PORT;
PORT=&PORTB;
*PORT=0xFF;
Создаем указатель PORT. Далее узнаем адрес PORTB и фигачим в этот порт данные, по идее должно работать, но студия радостно виснет, что самое смешное то, что она показывает 0 варингов..

Кстати пробовал разные варианты char int unsykned char/int..

В чем косяк?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.05.2010, 19:39
Ответы с готовыми решениями:

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно....

Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей?
Доброго времени суток! Задался теоретическим вопросом. Читал пример из книги Лафоре...

Через указатели на указатели посчитать сумму двух чисел и записать в третье
1. Через указатели на указатели посчитать сумму двух чисел и записать в третье. 2. Написать...

Указатели на указатели с числами. Почему можно присвоить число в 4-ый элемент, если массив из 2 элементов?
Есть массив int **mas; mas=new int*; // выделил место под пять строк, верно ? mas=new int;//...

Есть три переменные. Используя указатели на указатели, поменять значение максимальной и минимальной переменной
Мой код. #include <iostream> #include <stdlib.h> #include<iomanip> using namespace std; ...

14
xroymom
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 727
26.05.2010, 19:51 2
По идее надо таки char, sykned или unsykned. А так - работает, у меня по крайней мере.
При -O0 в окне дизассемблера даже видно, что все как и должно быть.

Код
#include <avr/io.h>

int main(void)
{
unsykned char *PORT;

PORT=&PORTB;

*PORT=0xFF;

while(1)
{
}

return 0;
}
0
Smypir
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 127
26.05.2010, 19:57 3
Build succeedid wyth 1 Warnings...
../test.c:11: warning: assyknment discards quotyfiers from pointer target type
Вот так, и ничего не рабоает)) опять все висет..

Код
#define F_CPU 16000000
#include <avr/io.h>

int main(void)
{
unsykned char *PORT;
PORT=&PORTB;
*PORT=0xFF;

char i=0;
char b=0;

while(1)
{

i++;
b=i;
}

return 0;
}
0
Smypir
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 127
26.05.2010, 20:03 4
ха.. Все таки работает, только с unsykned int, адрес же 2 байта в авре. Теперь допытываюсь почему студия на этом месте виснет.

Кстати узнал что работает, когда на паузу поставил и посмотрел порты...
0
26.05.2010, 20:03
xroymom
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 727
26.05.2010, 20:03 5
Ну варнинг у меня тоже вылазит, от него можно избавиться явно приведя тип указателя PORT=(unsykned char*)&PORTB;
А почему виснет - хз. У меня студия 4.18.692, winavr - 20080407
0
xroymom
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 727
26.05.2010, 20:04 6
Цитата Сообщение от Smypir
ха.. Все таки работает, только с unsykned int, адрес же 2 байта в авре. Теперь допытываюсь почему студия на этом месте виснет.

Кстати узнал что работает, когда на паузу поставил и посмотрел порты...
Адрес 2 байта, но указывает же он на однобайтный порт. Если ты так запишешь что-то по этому указателю, у тебя в следующий по списку регистр мусор попадет.
0
Smypir
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 127
26.05.2010, 20:07 7
да, верно..
У меня 4.18.692 WinAVR-20100110..
0
Smypir
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 127
26.05.2010, 20:16 8
Вот, все, разобрался. Там просто -Os стояло.. Непонятно правда почему так коряво работало, ну да ладно..
0
projists.ork.uo
0 / 0 / 0
Регистрация: 26.05.2010
Сообщений: 25
29.05.2010, 14:13 9
Цитата Сообщение от Smypir
Вот, все, разобрался. Там просто -Os стояло.. Непонятно правда почему так коряво работало, ну да ладно..
Похоже что для того что бы при -Os оставалось корректным поведение, нужно при декларации делать инициализацию = NULL;
Попробуйте, должно получиться по идее.
Вообще флаг -Os злой, не стоит на него нажимать ))
0
sovomt
0 / 0 / 0
Регистрация: 26.01.2010
Сообщений: 117
30.05.2010, 13:34 10
Флаг -Os на gcc-avr дает ощутимую экономию места. А делать инициализацию NULLом вообще полезно.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
30.05.2010, 16:37 11
а можно узнать? зачем полезно делать инициализацию NULLом?
и дело может не в -Os, а в том, что кто-то где-то не написал volatile?
вы подумайте, как тогда вообще что-то работает с -Os?
0
xroymom
0 / 0 / 0
Регистрация: 24.01.2010
Сообщений: 727
30.05.2010, 16:46 12
Цитата Сообщение от Ymk
зачем полезно делать инициализацию NULLом?
ну кагбэ вообще инициализировать переменные полезно
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
31.05.2010, 09:39 13
возможно, только если ты совсем не внимательный или пишешь проги левой пяткой. раз указатель есть, значит ты где-то его обязательно инициализируешь, и эти лишние инициализации - лишний код. и ОСОБЕННО на мк.
0
projists.ork.uo
0 / 0 / 0
Регистрация: 26.05.2010
Сообщений: 25
03.06.2010, 19:09 14
Цитата Сообщение от Ymk
возможно, только если ты совсем не внимательный или пишешь проги левой пяткой. раз указатель есть, значит ты где-то его обязательно инициализируешь, и эти лишние инициализации - лишний код. и ОСОБЕННО на мк.
Вы не совсем правы, объясню
правы в том что:
- на МК мало места, и лишняя инициализация это как минимум 1 такт, или 1 инструкция в зависимости от архитектуры
- в любой программе можно ошибиться

НЕПРАВЫ в том что:
- на ошибки не нужно проверять, будучи уверным в своей корректности написания.
- Как Вы говорите, не нужно инициализировать переменные
...это не правильно, и вот вам краткий список причин, почему это неправильно и что может случиться.

Объясняю причины
-> Проверять указатели нужно всегда на ноль! особенно входных параметров и любых переменных с указателем(зависит от алгоритма).
-> программа на С должна быть портируемая, и везде работать корректно
-> должна работать гарантировано, особенно при внешний воздействиях (например ЭМС)

ОСОБЕННО НА МК - НЕОБХОДИМО ВСЕГДА ПРОВЕРЯТЬ УКАЗАТЕЛИ !!!
Это правило которое должно всегда соблюдаться. Для сравнения еще объясню:
-> что может произойти плохого если не соблюдать это правило? Чернобыль помните? Эквивалентно.

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

из за не инициализированных переменных указателей в ноль и отсутствие проверки - распространено популярно сообщение об ошибке - сигментайшн фаулт (Segmentation fault), срыв стэка... итд.

Не стоит этим жертвовать ради лени/нежелания написать инициализацию и сделать лишнюю проверку, код т этого медленнее не станет.

.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
06.06.2010, 15:19 15
Цитата Сообщение от projists.ork.uo
на ошибки не нужно проверять, будучи уверным в своей корректности написания.
если у вас программа 10 раз запрашивает выделение памяти 10 байт, при этом вы знаете, что вам гарантированно они выдадутся (зная особенности функции выделения памяти и остальной алгоритм) - зачем проверять???
Цитата Сообщение от projists.ork.uo
Проверять указатели нужно всегда на ноль! особенно входных параметров и любых переменных с указателем(зависит от алгоритма).
вот в примере выше я НЕ буду проверять и буду прав:) буду проверять только тогда, когда я чего-то не знаю или в чем-то не уверен. так же и со входными параметрами. если мне алгоритм гарантирует, что указатель всегда будет не равен 0, то я и проверять это не буду (например, при вызове всегда передаю адрес существующей переменной).
Цитата Сообщение от projists.ork.uo
программа на С должна быть портируемая, и везде работать корректно
согласен, но это здесь не при чем. по стандарту - память под локальными переменными не инициализированная, это нужно учесть в алгоритме. malloc МОЖЕТ возвращать NULL, это тоже нужно учесть.
Цитата Сообщение от projists.ork.uo
что может произойти плохого если не соблюдать это правило? Чернобыль помните? Эквивалентно.
не корректный пример. там у кого-то в голове указатель не инициализировался?;))
Цитата Сообщение от projists.ork.uo
в разы, или в десятки раз, улучшилась стабильность его функционирования после явной инициализации значением и явной проверки указателей.
а реальное объяснение у вас этому есть? "просто по факту стало лучше" - это ламеризм, извините.
projists.ork.uo писал(а):
из за не инициализированных переменных указателей в ноль и отсутствие проверки - распространено популярно сообщение об ошибке - сигментайшн фаулт (Segmentation fault), срыв стэка... итд.
это-то все известно, но здесь эти быдлокодеры просто затупили и ничего больше. проверять надо тогда, когда и правда надо проверять, а не "а вдруг чо".
срыв стека, как мне кажется, от этого не бывает.
0
06.06.2010, 15:19
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.06.2010, 15:19

Указатели на указатели, как правильно разыменовать, где ошибка?
1)Есть класс: Shape - абстрактный; у него есть классы наследники: Circle, Triangle. 2)Eсть...

Указатели на указатели: для чего они могут понадобятся?
Изучаю C++, дошёл до указателей на указатели. Там пишут что эта тема не обязательна. Для чего они...

Зачем нужны все эти указатели (или не указатели)
Зачем надо DWORD, HANDLE, LPVOID?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru