Тупость или подводный камень

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

Ладно, забили.

Подразумевая, я говорил о том, что если я объявлю переменную, и не присвою ей значение, то это значение будет НОЛЬ! И это факт!
Поэтому все равно со strlen непонятно... есть строка, и есть ее размер, почему она должна дальше рыть память?

А ваще, может я и ни в чем не разбираюсь, написав туеву хучу прог, но вот задачка:

Приходит заказчик, - Напишите мне прогу под 90S1200, чтобы она выполняла вот такое:

for(i = 0; i<360; i++){
arg = 2*M_PI*i/360;
a1 = sin(arg) + i;
//printf("%3d : %f %f\n",i,a1,cos(arg));
printf("%f\n",3.14/i);
}

А вы ему, - Дядька, те че, бахнулся, да на такой код как минимум мега8 нужна, иди плату переделывай!

И вот это действительно смешно, и детям такое, точно читать нельзя.
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

Мнда, действительно, я тоже в иаре поставил галочку printf large, для чисел типа float, и точно, вместо десятков байт, прога автоматически начинает весить 4К.
А ведь раньше и на 51-вых не такие расчеты делали.
Выходит, хочешь простоты и скорости в написании программы с помощью библиотечных функций - смотри сразу в сторону "больших" чипов.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

__Alexander, вы или очень ловко прикидываетесь, или на самом деле совершенно не рубите в теме.

Подразумевая, я говорил о том, что если я объявлю переменную, и не присвою ей значение, то это значение будет НОЛЬ! И это факт!
ЭТО НЕ ФАКТ!!! далеко не любые явно непроинициализированные переменные будут равны нулю по умолчанию!!! вы, как всегда, ткнули пальцем в небо.

Про остальное я вообще молчу... в AT90S1200 отсутствует ОЗУ, написать на Си для него программу вообще проблематично...

P.S. сомневаюсь, что вы вообще способны вычислить синус, не прибегая к библиотечной функции... не поделитесь кодом для этого? ;)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

ARV писал(а): далеко не любые явно непроинициализированные переменные будут равны нулю по умолчанию!!! вы, как всегда, ткнули пальцем в небо.

Пока никогда не сталкивался.

ARV писал(а):Про остальное я вообще молчу... в AT90S1200 отсутствует ОЗУ, написать на Си для него программу вообще проблематично...
P.S. сомневаюсь, что вы вообще способны вычислить синус, не прибегая к библиотечной функции... не поделитесь кодом для этого? ;)


О! Именно проблематично! Но можно, если захотеть, просто никто не хочет, потому-что есть стандартные библиотеки. А ведь раньше таких ресурсов у МК не было, но тем не менее, аппаратура и в космос летала, и расчеты поболее этих делала... тогда почему-то находились такие энтузиасты. Может потому что партия сказала?

ARV писал(а):ну, если вам не нужно понимать, что делает ваша программа - то тогда конечно... только в этом случае лучше не программы писать, а пиво пить...


Да, пивасика бы сейчас...

А про тип данных, я опять таки, сказал что мне не надо знать только потому, что, либо я, вижу что я пишу в массив, либо мне никто не мешает взять отдельный элемент и посмотреть что там. Так как там по-любому число от 0 до 255. Но то что с ним делать, это зависит от конкретной ситуации. Если это уапп, то обработать этот массив можно и на приемной стороне, а можно и в виде hex смотреть (смотря что требуется), а вот если это индикатор на базе 44780, тогда да, перед выводом необходимо подготовить его для удобоваримого для данного контроллера вида.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

по-вашему как раз получается, что вы не видите, что у вас в массиве... вот strlen у вас лажу возвращает - и вы первым делом бочку катите на функцию, а не на свое "зрение", точнее, понимание... просто удивительно, как вы смогли написать много-много программ с такими понятиями...

а про минимализм мне не надо рассказывать - я с ассемблером не один год работал, и в том числе с 51-ыми тоже.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

ARV писал(а):по-вашему как раз получается, что вы не видите, что у вас в массиве... вот strlen у вас лажу возвращает - и вы первым делом бочку катите на функцию, а не на свое "зрение", точнее, понимание... просто удивительно, как вы смогли написать много-много программ с такими понятиями...


Че сразу качу бочку? а может просто хотел узнать вразумительный ответ. А ответ будет таким, что при объявлении более одной строки в массиве - это уже не строки, а указатели на первые символы этих строк автоматически. И поэтому без * компилятор ругается. И strlen() после этого продолжает нормально работать. Вот соссно это я и хотел услышать. И кто знал что именно этого этот strlen хотел?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

__Alexander писал(а):И кто знал что именно этого этот strlen хотел?
тот знал, кто перед тем, как взяться за дело, изучает свой инструмент. :))) как ни двусмысленно это звучит :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ikarab
Опытный кот
Сообщения: 828
Зарегистрирован: Пн мар 16, 2009 21:40:57
Контактная информация:

Сообщение ikarab »

ARV писал(а): в AT90S1200 отсутствует ОЗУ, написать на Си для него программу вообще проблематично...


Наверно на страничке 4 моего курса можно посмотреть про компилятор ICC для AVR без ОЗУ , скачать его и писать на Си. Ноу проблем !
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

ikarab писал(а):Наверно на страничке 4 моего курса можно посмотреть про компилятор ICC для AVR без ОЗУ , скачать его и писать на Си. Ноу проблем !
вам доводилось это делать? много программ написали для таких бзОЗУшных МК? на WinAVR народ тоже извращается - для тини15 пишет, но именно это я и называю "проблематично". я ведь не написал "невозможно"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

ARV писал(а):тот знал, кто перед тем, как взяться за дело, изучает свой инструмент. :))) как ни двусмысленно это звучит :)))


А тут по сути дело не в самой strlen, а в объявлении строк, и если компилятор не сругнулся, а в результате я получаю бред (даже не ошибку типа -1), то значит все правильно. со стороны компилятора.

А то, что я с этим не сталкивался, то может это и к лучшему, если вывести на ЖКИ, то пишу функцию вывода данных на конкретный порт и стробы на конкретные ноги, если в уарт, то тоже самое, есть putstring, которая в зависимости от длины строки вызывает функцию putchar. И это все в файле uart.c, который я вижу, и могу перенаправить на любой порт с любой скоростью. И не считаю, что я делаю неправильно, не используя printf. А может даже лучше, сэкономив на величине результирующего кода.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

__Alexander писал(а):А то, что я с этим не сталкивался, то может это и к лучшему, если вывести на ЖКИ, то пишу функцию вывода данных на конкретный порт и стробы на конкретные ноги, если в уарт, то тоже самое, есть putstring, которая в зависимости от длины строки вызывает функцию putchar. И это все в файле uart.c, который я вижу, и могу перенаправить на любой порт с любой скоростью. И не считаю, что я делаю неправильно, не используя printf. А может даже лучше, сэкономив на величине результирующего кода.
а вы попробуйте в putstring (блин, как же это вы - это же библиотечная функция!!!) передать свой первоначально названный str[5] = {1,2,3,4,5} - что она выведет? 5 или 8 символов? или 15? блин, вот эти библиотечные функции - одна морока... :)))

а на счет результирующего кода - если вы ставите себе задачу примитивную - вы и решение получаете примитивное, а если задачу ставить более серьезно - никуда не деться, размер вылезет боком...

для смеху: напишите самостоятельно функцию, которая выведет число float так, чтобы перед запятой было обязательно 3 символа (ненулевые должны быть пробелами), а после запятой - тоже 3... а когда напишите, скормите ей число 1.28365E8 и посмотрите, что получится... а после этого посмотрим, есть ли смысл в printf или нет :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

ARV писал(а):а вы попробуйте вputstring (блин, как же это вы - это же библиотечная функция!!!) передать свой первоначально названный str[5] = {1,2,3,4,5} - что она выведет? 5 или 8 символов? или 15? блин, вот эти библиотечные функции - одна морока... :)))


я имел ввиду не библиотечную функцию. А вот эту:

void _putchar(unsigned char in_char)
{
while (!(CHECKBIT(UCSRA, UDRE)))
{
}

UDR = in_char;
}

void _putstring(char *s)
{
unsigned int i,q;
i = strlen(s);
for(q=0;q<i;q++)
{
_putchar(s[q]);
}
}

И на этот вопрос ответ даю сходу:
Вот прога, ответ в приложении, результат ессно в hex, но строку тоже правильно выводит.

int main(void){

char str[5] = {3,4,5,6,7};
USART_Init(8); // 57600 при 8Мгц
_putstring(str);
for(;;){};
}

ARV писал(а):для смеху: напишите самостоятельно функцию, которая выведет число float так, чтобы перед запятой было обязательно 3 символа (ненулевые должны быть пробелами), а после запятой - тоже 3... а когда напишите, скормите ей число 1.28365E8 и посмотрите, что получится... а после этого посмотрим, есть ли смысл в printf или нет :)))


Вот на этот вопрос с ходу не отвечу, но уверен что напишу. А почему не напишу, не используя printf?
Вложения
prot.jpg
(9.59 КБ) 382 скачивания
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

начну с конца.
я думаю, что с горем пополам напишите вы свой вариант printf - вопрос лишь в том, сколько удет на это времени и как это будет работать - судя по ранее сказанному вами работать будет кривенько, размерчик будет не маленький...

а теперь по вашему примеру "сходу". есть ряд вопросов:
в вашем коде вы используете функцию strlen. это во-первых, противоречит вашим принципам, а во-вторых, почему ни с того ни с сего эта функция вдруг вернула вам 5, а не 8, как раньше? вам не кажется это странным?

а вот как сработает такой вариант у вас - он ведь практически не отличается от вашего:

Код: Выделить всё

char str[5] = {3,4,5,6,7}; 

int main(void){
USART_Init(8); // 57600 при 8Мгц
_putstring(str);
for(;;){};
}
;)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

Срабатывает абсолютно одинаково.

Мдна, признаюсь, с задаванием вопросов у меня есть проблема, меня не всегда можно понять, что я хочу. короче, на пальцах.
Если если я объявлю две разных строки, то при указании размера первого, даже больше чем я действительно укажу, то при вычислении размера второй, ее длина вычисляется правильно, но какого она прибавляется к первой???

char str0[10] = "12345";
char str1[6] = "123456";

_putchar(strlen(str0));
_putchar(strlen(str1));

так вот, хотя указано 10, размер первой строки возвращается 5, а вот размер str1 уже 6 плюс 5, то есть 11, проверил, если размер второй строки сделать 5, то вернется 10.

А если вот так,

char str0[] = "12345";
char str1[] = "123456";

то все нормально, первая 5, вторая шесть.

И на засыпку, если вот-так:

char str0[] = {1,2,3,4,5};
char str1[] = {1,2,3,4,5,6};

_putchar(strlen(str0));
_putchar(strlen(str1));

то тут уже все равно, по-любому второй результат будет суммой обеих.
А если по отдельности, комментируя строки, результаты нормальные.
Я знаю, что есть этому нормальное объяснение, но тем не менее, почему в той-же _putstring strlen не возвращает сумму всех предыдущих вызовов этой функции.

И еще, если выводить строки,

char str0[10] = "123";
char str1[4] = "4567";
_putchar(strlen(str0));
_putchar(strlen(str1));
_putstring(str0);
_putstring(str1);

получается что выводит 1234567123, т.е. вторая строка дополняется в конце первой строкой.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Сообщение urry »

Интересно, Вы читаете, что Вам пишут ???
Строка должна заканчиваться 0 , поэтому в выражении
char str0[10] = "12345"; - он есть,
а char str1[6] = "123456"; - его уже некуда сунуть, Вы заняли полностью
размер.
str1[7] = "123456"; - уже будет работать
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

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

str[] - это объявление строки, str[10] - это объявление массива из 10 элементов. строка отличается от массива char тем, что всегда и безусловно дополняется завершающим нулем, массив же никогда не добавляет ничего к тому, что задано для него в инизиализирующих фигурных скобках.

статические (глобальные) массивы по умолчанию инициализируются нулями, поэтому если вы для массива с размерностью 10 зададите только 5 первых чисел - остальные будут нулями. т.е. в этом случае массив по своей сути оказывается тем же, что и строка (ноль в конце есть).

strlen ищет в строке (или массиве байтов - ей все равно) первый нулевой байт, считая количество ненулевых. когда вы задаете массивы фиксированной размерности и инициализируете их полностью - никаких нулей ни внутри них, ни между нет - и strlen, начиная с начала первого массива может перебрать все содержимое ОЗУ до тех пор, пока не встретит 0. если чисто случайно в ОЗУ не найдется ни одного нуля - эта функция вообще может зациклиться (наверное - я не уверен точно), или вернуть потрясающее значение -1 или еще что-то странное.

когда вы разберетесь, в чем разница между
str[] = "123" и str[3] = {1,2,3}, вы перестанете удивляться "странностям".

для понимания можете еще побаловаться с sizeof() - передав ей разные варианты ваших массивов и строк :) очень может быть, что и в этом случае вы обнаружите что-то удивителное для себя :)

кстати, "нормальные" программисты пишут вашу функцию (что вы ранее приводили в качестве примера) так:

Код: Выделить всё

void _putstring(char *s) { 
   while(*s) _putchar(*s++);
}
а вы что-то про размер кода говорили :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

urry писал(а):Интересно, Вы читаете, что Вам пишут ???
Строка должна заканчиваться 0 , поэтому в выражении
char str0[10] = "12345"; - он есть,
а char str1[6] = "123456"; - его уже некуда сунуть, Вы заняли полностью
размер.
str1[7] = "123456"; - уже будет работать


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

Это отголоски прошлого, 86 размещает стек с точностью до наоборот 51 и AVR.
Последний раз редактировалось __Alexander Чт июл 09, 2009 22:54:29, всего редактировалось 2 раза.
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Сообщение __Alexander »

ARV писал(а):кстати, "нормальные" программисты пишут вашу функцию (что вы ранее приводили в качестве примера) так:

Код: Выделить всё

void _putstring(char *s) { 
   while(*s) _putchar(*s++);
}
а вы что-то про размер кода говорили :)))


В некоторых проектах и это есть, но че-то на код не сильно влияло.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»