jenya7 0 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Как же тогда делать? void Reverse(char *str, int len) { int i=0, j=len-1, temp; while (i<j) { temp = str[i]; str[i] = str[j]; str[j] = temp; i++; j--; } } int IntToStr(int x, char str[], int d) { int i = 0; while (x) { str[i++] = (x%10) + '0'; x = x/10; } // If number of digits required is more, then // add 0s at the beginning while (i < d) str[i++] = '0'; Reverse(str, i); str[i] = '\0'; return i; } // Converts a floating point number to string. void FtoA(float n, char *res, int afterpoint) { // Extract integer part int ipart = (int)n; // Extract floating part float fpart = n - (float)ipart; // convert integer part to string int i = IntToStr(ipart, res, 0); // check for display option after point if (afterpoint != 0) { if (ipart==0) res[i++] = '0'; res[i] = '.'; // add dot // Get the value of fraction part upto given no. // of points after dot. The third parameter is needed // to handle cases like 233.007 fpart = fpart * pow(10, afterpoint); IntToStr((int)fpart, res + i + 1, afterpoint); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее. Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. :wacko: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. :wacko: а что плохого если строки лежат во txt секции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 24 июля, 2018 Опубликовано 24 июля, 2018 (изменено) · Жалоба а что плохого если строки лежат во txt секции? Да если бы они лежали только в .text... Изменено 24 июля, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба а что плохого если строки лежат во txt секции? В какой txt-секции? Так как Вы пишете, все Ваши строки и указатели на них лежат в ОЗУ + инициализирующие значения лежат во флешь. А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь. Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет. Поправка: если возвращать из функции по значению структуру, содержащую строку, эта структура будет временно создана на стеке. Но это совсем другой случай, конечно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет. попробуйте: char t[] = "строка"; где будет создана t? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба попробуйте: char t[] = "строка"; где будет создана t? Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба я создам отдельную тему в В помощь начинающему > Программирование - где хранить строки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе. Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так? Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет. Копию в ОЗУ точно не будет создавать. В порядке ликбеза: объявление переменной и список аргументов функции - это совсем разные штуки. Какое-то совпадение в семантике есть, но есть и кардинальные различия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет.Это жульничество, от такого компилятор не защищает. Вы напрасно спорите с jcxz, он прав. Более того, gcc уже давно ругается на char * text = "слава мне, победителю драконов"; warning: ISO C++ forbids converting a string constant to ‘char*’ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Вы напрасно спорите с jcxz, он прав. Нет, не напрасно. Я спорю вот с этим: А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти Это очевидное заблуждение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Это очевидное заблуждение. Вы правы. У меня в проекте вся менюшка выполнена в стиле lcd.Printx(0, " си_не_знаю_пишу_как_попало ");, где void Printx(uint8_t x,char *s);. Заглядываем в map по модулю меню. Module ro code ro data rw data ------ ------- ------- ------- Menu.o 2 436 7 20 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 24 июля, 2018 Опубликовано 24 июля, 2018 · Жалоба Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет. Копию в ОЗУ точно не будет создавать. Ну я вообще-то говорю не про явное приведение типа. А когда вообще без приведения типа функции, принимающей указатель на переменную, передаётся константа. Явным приведением типа программист просто говорит, что в данном конкретном случае здесь передаётся "не то что можно ожидать по типу объявленного символического имени, а нечто другое". Если функция использует принятый указатель только для операций чтения, то при объявлении такой функции надо этому указателю (аргументу) назначать модификатор const. Частный случай - член-функция класса, использующая члены класса только на чтение (и вызывающая только const член-функции класса) - тоже должна объявляться с модификатором const. Если функция использует принятый аргумент-указатель и для операций записи, то тогда нужно описывать без слова const. И компилятор, при передаче аргумента такой фукции, будет проверять чтобы const-указатели не передавались в не-const аргументы функций. Вы правы. У меня в проекте вся менюшка выполнена в стиле lcd.Printx(0, " си_не_знаю_пишу_как_попало ");, где void Printx(uint8_t x,char *s);. Заглядываем в map по модулю меню. Значит Ваш компилятор в этом случае не проверяет соответствие типов передаваемых данных и аргументов функции. И плохо. Это его недостаток. Но это не значит что все компиляторы так делают. Это очевидное заблуждение. Почему? В чём разница между: char t[] = "XXXX"; и void Func(char *) ? И первом случае Вы говорите компилятору, что хотите иметь переменную (с начальным значением), а значит - хотите иметь возможность записи в неё. И во-втором случае говорите ему, что функция Func() хочет иметь возможность записи в принимаемый ею аргумент (т.е. - она принимает указатель на переменную). В чём принципиальная разница? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться