Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
под переменную выделяется минимум 1 Байт
а сколько выделяется памяти под указатель на оную переменную ?
а сколько выделяется памяти под указатель на оную переменную ?
Tell Me The Truth
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Размер зависит от платформы. Он должен быть способным адресовать всю область памяти.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
FreshMan писал(а):для 8 битных AVR
размер указателя обычно совпадает с размером int для платформы. собственно, с адресным пространством памяти размер int и [должен быть]связан... но, естественно, полно исключений.
WinAVR (avr-gcc) придерживается мнения, что указатель имеет размер 16 бит, причем даже указатель на flash, хотя объем flash у AVR встречается и поболее 64К.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
имеется два массива
и указатель
размер оного указателя равен 1 байт ?
Код: Выделить всё
unsigned char BrightnessOldDigits[6]={10,10,10,10,10,10};
unsigned char BrightnessNewDigits[6]={10,10,10,10,10,10};
и указатель
Код: Выделить всё
uint8_t *p_brightness[12] = {&BrightnessOldDigits[2], // когда var=0
&BrightnessOldDigits[3], // когда var=1
&BrightnessOldDigits[4], // когда var=2
&BrightnessOldDigits[5], // когда var=3
&BrightnessNewDigits[0], // когда var=4
&BrightnessNewDigits[1], // когда var=5
&BrightnessNewDigits[2], // когда var=6
&BrightnessNewDigits[3], // когда var=7
&BrightnessNewDigits[4], // когда var=8
&BrightnessNewDigits[5], // когда var=9
&BrightnessOldDigits[0], // когда var=10
&BrightnessOldDigits[1]}; // когда var=11
размер оного указателя равен 1 байт ?
Tell Me The Truth
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
uint8_t *p_brightness
uint16_t *p_brightness
uint32_t *p_brightness
для AVR будут все по 16 бит.
А вот при разыменовании происходит доступ к 8, 16 или 32 битам соответственно.
uint16_t *p_brightness
uint32_t *p_brightness
для AVR будут все по 16 бит.
А вот при разыменовании происходит доступ к 8, 16 или 32 битам соответственно.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
FreshMan писал(а):имеется два массива и указатель
на самом деле у вас МАССИВ УКАЗАТЕЛЕЙ
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
а допускается ли такое безобразие
Код: Выделить всё
uint8_t p_brightness[12]={BrightnessOldDigits[2], // êîãäà var=0
BrightnessOldDigits[3], // êîãäà var=1
BrightnessOldDigits[4], // êîãäà var=2
BrightnessOldDigits[5], // êîãäà var=3
BrightnessNewDigits[0], // êîãäà var=4
BrightnessNewDigits[1], // êîãäà var=5
BrightnessNewDigits[2], // êîãäà var=6
BrightnessNewDigits[3], // êîãäà var=7
BrightnessNewDigits[4], // êîãäà var=8
BrightnessNewDigits[5], // êîãäà var=9
BrightnessOldDigits[0], // êîãäà var=10
BrightnessOldDigits[1]}; // êîãäà var=11
Tell Me The Truth
Re: Вопросы по С/С++ (СИ)
FreshMan писал(а):а допускается ли такое безобразие
Че эт безобразие-то?!! Вполне естественно.
Код: Выделить всё
*p_brightness=BrightnessOldDigits[2] // имя массива указатель на нуевой элемент
p_brightness[2]=BrightnessOldDigits[4] // Одинаково
*(p_brightness+2)=BrightnessOldDigits[4] //
uint8_t p_brightness[]={......} // можно число не указывать если инициализируете
Re: Вопросы по С/С++ (СИ)
Привет всем.
Создаю программу приёма пакета через uart, используя прерывание.
Код:
Конец пакета буду определять просто - по разрыву по времени между принятыми символвми более 100мс.
Проблема в процедуре addItem (написал по докам из яндекса):
Код:
При первом проходе через процедуру, добавляется символ к массиву и возвращается изменённый массив нормально.
При втором проходе, помимо добавления символа добавляется ещё и символ '.'.
При третьем проходе, всё виснет.
Сперва грешил на символ \0 в конце строки, но вроде он ставится автоматом, и не надо заботиться о его добавлении.
В чём проблема?
Создаю программу приёма пакета через uart, используя прерывание.
Код:
Код: Выделить всё
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_VECTOR_PRE (void)
{
char buf = UCA0RXBUF; //сбрасываем прерывание
addItem(ch_exp,buf); //добавляем символ buf к массиву символов ch_exp
UARTWriteString(ch_exp);
//далее заводим таймер на 100мс
}Конец пакета буду определять просто - по разрыву по времени между принятыми символвми более 100мс.
Проблема в процедуре addItem (написал по докам из яндекса):
Код:
Код: Выделить всё
void addItem(char *&c, char sim)
{
char *tt; //использую свой метод определения длины строки, это наверно почти бред:)
tt = c;
int ii = 0;
while (*tt)
{
ii++;
tt++;
}
char *t = new char[ii+1]; //но даже если задавать размерность вручную, то тоже виснет
for (int i=0; i<ii;i++)
t[i] = c[i];
t[ii] = sim;
delete[] c;
c = t;
}
При первом проходе через процедуру, добавляется символ к массиву и возвращается изменённый массив нормально.
При втором проходе, помимо добавления символа добавляется ещё и символ '.'.
При третьем проходе, всё виснет.
Сперва грешил на символ \0 в конце строки, но вроде он ставится автоматом, и не надо заботиться о его добавлении.
В чём проблема?
- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
VLeshka писал(а):Код: Выделить всё
void addItem(char *&c, char sim)
{
char *tt; // это бред
tt = c;
В чём проблема?
Как ты приравниваешь указатель на адрес переменной к указателю на переменную?
Re: Вопросы по С/С++ (СИ)
GARMIN писал(а):VLeshka писал(а):Код: Выделить всё
void addItem(char *&c, char sim)
{
char *tt; // это бред
tt = c;
В чём проблема?
Как ты приравниваешь указатель на адрес переменной к указателю на переменную?
Спасибо за указание на эту ошибку. Накидал код:
Код: Выделить всё
void addItem(char &c, char sim) //тут была ошибка
{
char *tt;
tt = &c;
int ii = 0;
while (*tt)
{
ii++;
tt++;
}
char *t = new char[ii+1];
for (int i=0; i<ii;i++)
{
t[i] = c;
c++;
}
t[ii] = sim;
c = t[0];
}
и вызываем его:
Код: Выделить всё
addItem(ch_exp[0],'a');Вроде работает, но так же с "фокусами в конце массива". Доберусь до компа - проверю досконально (прошлой ночью времени было мало).
- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
void addItem(char &c, char sim) //тут была ошибка
{}
и вызываем его:
addItem(ch_exp[0],'a');
Опять двадцать пять:
ch_exp[0] передаётся по значению.
А ты объявляешь его адресом:
char &c
Re: Вопросы по С/С++ (СИ)
GARMIN писал(а):Опять двадцать пять:
ch_exp[0] передаётся по значению.
А ты объявляешь его адресом:
char &c
спасибо.
Я после очередного сеанса связи с MSP430 понял, что мне надо изучать поставленную мною тему с "Hello world".
Итак, в обработчике прерывания uart-порта при приёме, я написал простенький код по добавлению символа к строке, и выводу этой строки обратно в uart [на комп, для наглядного контроля].
Код: Выделить всё
char *ch_exp="Mod";
int cnt=3;
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_VECTOR_PRE (void)
{
char buf = UCA0RXBUF; //сбрасываем прерывание
P1OUT ^= (BIT0 + BIT6); //вкл и выкл диоды
UARTWriteString(ch_exp); //выводит строку в uart; всегда нормально работает
UARTWriteString("Ура"); //всегда нормально работает
char *t = new char[cnt+1]; //здесь на второй раз зависает
for (int i=0; i<cnt;i++)
t[i] = ch_exp[i];
t[cnt] = 'a';
t[cnt+1] = '\0';
cnt++;
ch_exp = t;
UARTWriteString(ch_exp);
}
При первом проходе через этот код всё нормально. Но не могу понять, почему намертво зависает при втором проходе на строке:
Код: Выделить всё
char *t = new char[cnt+1];Указатель t - локальный и не требует такого удаления:
Код: Выделить всё
//delete(t); //впрочем, вставлял - не помогаетУпёрся уже в тупой угол. В чём ошибаюсь???
- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
VLeshka писал(а):При первом проходе через этот код всё нормально. Но не могу понять, почему намертво зависает при втором проходе на строке:Код: Выделить всё
char *t = new char[cnt+1];
Указатель t - локальный и не требует такого удаления
Упёрся уже в тупой угол. В чём ошибаюсь???
Каким ерундовым софтом ты пользуешься, если он тебе компилирует этот код без ошибок?
Ну разберись с указателями и массивами наконец. Почитай, чем отличается элемент массива от указателя на этот элемент.
Тебе дважды говорил разобраться. Опять те же грабли.
Жевать не буду. Читай учебник до просветления.
Re: Вопросы по С/С++ (СИ)
GARMIN писал(а):Каким ерундовым софтом ты пользуешься, если он тебе компилирует этот код без ошибок?
спасибо за наводку.
GARMIN писал(а):Ну разберись с указателями и массивами наконец. Почитай, чем отличается элемент массива от указателя на этот элемент.
Тебе дважды говорил разобраться. Опять те же грабли.
Жевать не буду. Читай учебник до просветления.
ок. Вопросы закончились.
- Goodefine
- Держит паяльник хвостом
- Сообщения: 906
- Зарегистрирован: Ср апр 16, 2008 13:22:54
- Откуда: Приднестровье, Тирасполь
Re: Вопросы по С/С++ (СИ)
GARMIN писал(а):Каким ерундовым софтом ты пользуешься, если он тебе компилирует этот код без ошибок?
Код: Выделить всё
char *t = new char[cnt+1];А где в этом коде ошибка? Стандартная операция выделения памяти под массив в куче с инициализацией указателя.
Жевать не буду. Читай учебник до просветления.
Гм.. категоричное заявление
спасибо за наводку.
Посмотрите чему равно cnt в момент выделения памяти. Вполне возможно что в этот момент переменная не инициализирована и содержит мусор, соответственно память выделиться не может. Поставьте также ловушку на исключение std::bad_alloc - скорее всего в него программа и влетает.
Указатель t - локальный и не требует такого удаления:Код: Выделить всё
//delete(t); //впрочем, вставлял - не помогает
Не знаю диалекта вашего С++, но обычно массив правильно удаляют так
Код: Выделить всё
delete[] t;Т.е. надо освобождать весь массив, а не указатель - и об этом надо сообщать компилятору
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Пожалуйста, не используйте выделение памяти в векторах прерываний. Пользуйтесь только статическими переменными. Это неправильно. Это занимает много времени и может привести к сбоям системы.
И, после использования, удаляйте переменные. Памяти может не хватить.
И таки да, в предыдущем посте протупил.
Буду внимательнее.
И, после использования, удаляйте переменные. Памяти может не хватить.
И таки да, в предыдущем посте протупил.
Re: Вопросы по С/С++ (СИ)
Волею случая, использую [глобальный] статический массив. Сделал инкремент массива по указателю, но всё равно это делал используя статический массив (создаю статический массив, указываю в конце символ '\0' и ставлю указатель на этот массив) - так что перешёл на статический массив, как и делается в примерах для MSP430 по всему интернету.
-
srg320
- Встал на лапы
- Сообщения: 85
- Зарегистрирован: Пт фев 01, 2013 17:47:26
- Откуда: Украина, Луганская область
Re: Вопросы по С/С++ (СИ)
Вопрос по С++.
Есть класс Свойства
и пример использования
Когда тип Свойства простой, то проблем нет, а когда типом Свойства является класс, то нет доступа к полям класса. Или по другому и нельзя, или я не правильно написал перегрузку оператора приведения типа в классе Property, а может есть другие варианты достичь желаемого результата. Пишу в IARе, но думаю разницы нет какой компилятор.
Хотелось бы писать так
так и красивее и проще читать
а не так
или так
Если кто знает, подскажите.
Заранее благодарен.
Есть класс Свойства
Спойлер
Код: Выделить всё
template<typename Type,
typename Owner,
Type (Owner::*Getter)(),
void (Owner::*Setter)(Type)>
class Property
{
protected:
Owner * m_owner;
public:
operator Type () const
{
return (m_owner->*Getter)();
}
Type get() const
{
return (m_owner->*Getter)();
}
void operator =(Type data)
{
(m_owner->*Setter)(data);
}
Property() :
m_owner(0)
{}
Property(Owner * const owner) :
m_owner(owner)
{}
};и пример использования
Спойлер
Код: Выделить всё
class Rectangle
{
public:
int X;
int Y;
int Width;
int Height;
Rectangle() :
X(0),
Y(0),
Width(0),
Height(0)
{}
};
class Control
{
private:
Rectangle bounds;
int width;
void setBounds(Rectangle value) { bounds = value;}
Rectangle getBounds() { return bounds; }
void setWidth(int value) { width = value;}
int getWidth() { return width; }
public:
Control() :
Bounds(this),
Width(this)
{}
Property<Rectangle, Control, &Control::getBounds, &Control::setBounds> Bounds;
Property<int, Control, &Control::getWidth, &Control::setWidth> Width;
};
int main()
{
int x, width;
Control* c = new Control();
width = c->Width;
x = ((Rectangle)c->Bounds).X; //такой вариант работает
x = c->Bounds.get().X; //и такой
Rectangle bounds = c->Bounds; //и такой
x = bounds.X;
x = c->Bounds.X; //!!! а такой - нет
return 0;
}Когда тип Свойства простой, то проблем нет, а когда типом Свойства является класс, то нет доступа к полям класса. Или по другому и нельзя, или я не правильно написал перегрузку оператора приведения типа в классе Property, а может есть другие варианты достичь желаемого результата. Пишу в IARе, но думаю разницы нет какой компилятор.
Хотелось бы писать так
Код: Выделить всё
x = c->Bounds.X; а не так
Код: Выделить всё
x = ((Rectangle)c->Bounds).X;Код: Выделить всё
x = c->Bounds.get().X;Если кто знает, подскажите.
Заранее благодарен.