Перейти к содержанию
    

Как же тогда делать?
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);
    }
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.

Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. :wacko:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. :wacko:

 

а что плохого если строки лежат во txt секции?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что плохого если строки лежат во txt секции?

Да если бы они лежали только в .text...

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что плохого если строки лежат во txt секции?

В какой txt-секции? Так как Вы пишете, все Ваши строки и указатели на них лежат в ОЗУ + инициализирующие значения лежат во флешь.

А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь.

Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет.

Поправка: если возвращать из функции по значению структуру, содержащую строку, эта структура будет временно создана на стеке. Но это совсем другой случай, конечно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет.

попробуйте:

char t[] = "строка";

где будет создана t?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

попробуйте:

char t[] = "строка";

где будет создана t?

Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я создам отдельную тему в В помощь начинающему > Программирование - где хранить строки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе.

Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так?

Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет. Копию в ОЗУ точно не будет создавать.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет.
Это жульничество, от такого компилятор не защищает. Вы напрасно спорите с jcxz, он прав. Более того, gcc уже давно ругается на char * text = "слава мне, победителю драконов";

warning: ISO C++ forbids converting a string constant to ‘char*’

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы напрасно спорите с jcxz, он прав.

Нет, не напрасно. Я спорю вот с этим:

А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти

Это очевидное заблуждение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это очевидное заблуждение.

Вы правы. У меня в проекте вся менюшка выполнена в стиле lcd.Printx(0, " си_не_знаю_пишу_как_попало ");, где void Printx(uint8_t x,char *s);. Заглядываем в map по модулю меню.

    Module                       ro code  ro data  rw data
    ------                       -------  -------  -------
    Menu.o                         2 436        7       20

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, не так. Явным приведением типа можно отсечь от указателя 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() хочет иметь возможность записи в принимаемый ею аргумент (т.е. - она принимает указатель на переменную). В чём принципиальная разница?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...