Подразумевая, я говорил о том, что если я объявлю переменную, и не присвою ей значение, то это значение будет НОЛЬ! И это факт!
Поэтому все равно со strlen непонятно... есть строка, и есть ее размер, почему она должна дальше рыть память?
А ваще, может я и ни в чем не разбираюсь, написав туеву хучу прог, но вот задачка:
Приходит заказчик, - Напишите мне прогу под 90S1200, чтобы она выполняла вот такое:
Мнда, действительно, я тоже в иаре поставил галочку printf large, для чисел типа float, и точно, вместо десятков байт, прога автоматически начинает весить 4К.
А ведь раньше и на 51-вых не такие расчеты делали.
Выходит, хочешь простоты и скорости в написании программы с помощью библиотечных функций - смотри сразу в сторону "больших" чипов.
ARV писал(а): далеко не любые явно непроинициализированные переменные будут равны нулю по умолчанию!!! вы, как всегда, ткнули пальцем в небо.
Пока никогда не сталкивался.
ARV писал(а):
Про остальное я вообще молчу... в AT90S1200 отсутствует ОЗУ, написать на Си для него программу вообще проблематично...
P.S. сомневаюсь, что вы вообще способны вычислить синус, не прибегая к библиотечной функции... не поделитесь кодом для этого?
О! Именно проблематично! Но можно, если захотеть, просто никто не хочет, потому-что есть стандартные библиотеки. А ведь раньше таких ресурсов у МК не было, но тем не менее, аппаратура и в космос летала, и расчеты поболее этих делала... тогда почему-то находились такие энтузиасты. Может потому что партия сказала?
ARV писал(а):
ну, если вам не нужно понимать, что делает ваша программа - то тогда конечно... только в этом случае лучше не программы писать, а пиво пить...
Да, пивасика бы сейчас...
А про тип данных, я опять таки, сказал что мне не надо знать только потому, что, либо я, вижу что я пишу в массив, либо мне никто не мешает взять отдельный элемент и посмотреть что там. Так как там по-любому число от 0 до 255. Но то что с ним делать, это зависит от конкретной ситуации. Если это уапп, то обработать этот массив можно и на приемной стороне, а можно и в виде hex смотреть (смотря что требуется), а вот если это индикатор на базе 44780, тогда да, перед выводом необходимо подготовить его для удобоваримого для данного контроллера вида.
по-вашему как раз получается, что вы не видите, что у вас в массиве... вот strlen у вас лажу возвращает - и вы первым делом бочку катите на функцию, а не на свое "зрение", точнее, понимание... просто удивительно, как вы смогли написать много-много программ с такими понятиями...
а про минимализм мне не надо рассказывать - я с ассемблером не один год работал, и в том числе с 51-ыми тоже.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):по-вашему как раз получается, что вы не видите, что у вас в массиве... вот strlen у вас лажу возвращает - и вы первым делом бочку катите на функцию, а не на свое "зрение", точнее, понимание... просто удивительно, как вы смогли написать много-много программ с такими понятиями...
Че сразу качу бочку? а может просто хотел узнать вразумительный ответ. А ответ будет таким, что при объявлении более одной строки в массиве - это уже не строки, а указатели на первые символы этих строк автоматически. И поэтому без * компилятор ругается. И strlen() после этого продолжает нормально работать. Вот соссно это я и хотел услышать. И кто знал что именно этого этот strlen хотел?
ikarab писал(а):Наверно на страничке 4 моего курса можно посмотреть про компилятор ICC для AVR без ОЗУ , скачать его и писать на Си. Ноу проблем !
вам доводилось это делать? много программ написали для таких бзОЗУшных МК? на WinAVR народ тоже извращается - для тини15 пишет, но именно это я и называю "проблематично". я ведь не написал "невозможно"...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):тот знал, кто перед тем, как взяться за дело, изучает свой инструмент. как ни двусмысленно это звучит
А тут по сути дело не в самой strlen, а в объявлении строк, и если компилятор не сругнулся, а в результате я получаю бред (даже не ошибку типа -1), то значит все правильно. со стороны компилятора.
А то, что я с этим не сталкивался, то может это и к лучшему, если вывести на ЖКИ, то пишу функцию вывода данных на конкретный порт и стробы на конкретные ноги, если в уарт, то тоже самое, есть putstring, которая в зависимости от длины строки вызывает функцию putchar. И это все в файле uart.c, который я вижу, и могу перенаправить на любой порт с любой скоростью. И не считаю, что я делаю неправильно, не используя printf. А может даже лучше, сэкономив на величине результирующего кода.
__Alexander писал(а):А то, что я с этим не сталкивался, то может это и к лучшему, если вывести на ЖКИ, то пишу функцию вывода данных на конкретный порт и стробы на конкретные ноги, если в уарт, то тоже самое, есть putstring, которая в зависимости от длины строки вызывает функцию putchar. И это все в файле uart.c, который я вижу, и могу перенаправить на любой порт с любой скоростью. И не считаю, что я делаю неправильно, не используя printf. А может даже лучше, сэкономив на величине результирующего кода.
а вы попробуйте в putstring (блин, как же это вы - это же библиотечная функция!!!) передать свой первоначально названный str[5] = {1,2,3,4,5} - что она выведет? 5 или 8 символов? или 15? блин, вот эти библиотечные функции - одна морока...
а на счет результирующего кода - если вы ставите себе задачу примитивную - вы и решение получаете примитивное, а если задачу ставить более серьезно - никуда не деться, размер вылезет боком...
для смеху: напишите самостоятельно функцию, которая выведет число float так, чтобы перед запятой было обязательно 3 символа (ненулевые должны быть пробелами), а после запятой - тоже 3... а когда напишите, скормите ей число 1.28365E8 и посмотрите, что получится... а после этого посмотрим, есть ли смысл в printf или нет
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
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, но строку тоже правильно выводит.
ARV писал(а):
для смеху: напишите самостоятельно функцию, которая выведет число float так, чтобы перед запятой было обязательно 3 символа (ненулевые должны быть пробелами), а после запятой - тоже 3... а когда напишите, скормите ей число 1.28365E8 и посмотрите, что получится... а после этого посмотрим, есть ли смысл в printf или нет :)))
Вот на этот вопрос с ходу не отвечу, но уверен что напишу. А почему не напишу, не используя printf?
начну с конца.
я думаю, что с горем пополам напишите вы свой вариант printf - вопрос лишь в том, сколько удет на это времени и как это будет работать - судя по ранее сказанному вами работать будет кривенько, размерчик будет не маленький...
а теперь по вашему примеру "сходу". есть ряд вопросов:
в вашем коде вы используете функцию strlen. это во-первых, противоречит вашим принципам, а во-вторых, почему ни с того ни с сего эта функция вдруг вернула вам 5, а не 8, как раньше? вам не кажется это странным?
а вот как сработает такой вариант у вас - он ведь практически не отличается от вашего:
Мдна, признаюсь, с задаванием вопросов у меня есть проблема, меня не всегда можно понять, что я хочу. короче, на пальцах.
Если если я объявлю две разных строки, то при указании размера первого, даже больше чем я действительно укажу, то при вычислении размера второй, ее длина вычисляется правильно, но какого она прибавляется к первой???
char str0[10] = "12345";
char str1[6] = "123456";
_putchar(strlen(str0));
_putchar(strlen(str1));
так вот, хотя указано 10, размер первой строки возвращается 5, а вот размер str1 уже 6 плюс 5, то есть 11, проверил, если размер второй строки сделать 5, то вернется 10.
то тут уже все равно, по-любому второй результат будет суммой обеих.
А если по отдельности, комментируя строки, результаты нормальные.
Я знаю, что есть этому нормальное объяснение, но тем не менее, почему в той-же _putstring strlen не возвращает сумму всех предыдущих вызовов этой функции.
Интересно, Вы читаете, что Вам пишут ???
Строка должна заканчиваться 0 , поэтому в выражении
char str0[10] = "12345"; - он есть,
а char str1[6] = "123456"; - его уже некуда сунуть, Вы заняли полностью
размер.
str1[7] = "123456"; - уже будет работать
возможно, вам надо было с первого моего поста не начинать споры и рассказы про странность поведения функций, а почитать книжки по Си... сейчас бы вопросов не было...
str[] - это объявление строки, str[10] - это объявление массива из 10 элементов. строка отличается от массива char тем, что всегда и безусловно дополняется завершающим нулем, массив же никогда не добавляет ничего к тому, что задано для него в инизиализирующих фигурных скобках.
статические (глобальные) массивы по умолчанию инициализируются нулями, поэтому если вы для массива с размерностью 10 зададите только 5 первых чисел - остальные будут нулями. т.е. в этом случае массив по своей сути оказывается тем же, что и строка (ноль в конце есть).
strlen ищет в строке (или массиве байтов - ей все равно) первый нулевой байт, считая количество ненулевых. когда вы задаете массивы фиксированной размерности и инициализируете их полностью - никаких нулей ни внутри них, ни между нет - и strlen, начиная с начала первого массива может перебрать все содержимое ОЗУ до тех пор, пока не встретит 0. если чисто случайно в ОЗУ не найдется ни одного нуля - эта функция вообще может зациклиться (наверное - я не уверен точно), или вернуть потрясающее значение -1 или еще что-то странное.
когда вы разберетесь, в чем разница между str[] = "123" и str[3] = {1,2,3}, вы перестанете удивляться "странностям".
для понимания можете еще побаловаться с sizeof() - передав ей разные варианты ваших массивов и строк очень может быть, что и в этом случае вы обнаружите что-то удивителное для себя
кстати, "нормальные" программисты пишут вашу функцию (что вы ранее приводили в качестве примера) так:
urry писал(а):Интересно, Вы читаете, что Вам пишут ???
Строка должна заканчиваться 0 , поэтому в выражении
char str0[10] = "12345"; - он есть,
а char str1[6] = "123456"; - его уже некуда сунуть, Вы заняли полностью
размер.
str1[7] = "123456"; - уже будет работать
Все, разобрался, идея в том, что в памяти компилятор почему начинает размещать их с конца.
Это отголоски прошлого, 86 размещает стек с точностью до наоборот 51 и AVR.
Последний раз редактировалось __Alexander Чт июл 09, 2009 22:54:29, всего редактировалось 2 раза.