ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
12 июля
414295 Топик полностью
fk0, легенда (31.05.2013 18:21 - 18:36, просмотров: 190) ответил Молодой коллега на char* pText = "Main Menu1"; "Main Menu1" компилятор должен положить строку в озу или во флеш?
Зайду издалека. cAmElcAsE дО дОбРа Не ДОвЕдёТ. И звёздочку ставить нужно слева от переменной сразу. Так до мозгов смысл быстрей доходит. По существу вопроса: в языке C строковые константы являются таки константами, если они являются константами, а не переменными. Чтобы это прочувствовать более наглядно следует скомпилировать исходник компилятором gcc с опцией -Wwrite-strings. Получим ругань: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default] для следующей строки исходника: char* pText = "Main Menu1"; Почему так: потому, что в первой строке тут переменной тип "указатель на переменный символ" присваивается "указатель на первый символ константной строки". Но без -Wwrite-strings мы это рискуем не увидеть. А во второй строке переменная типа "массив символов" инициализируется значением "Main Menu2" (из некой константной строки скрытой от программиста). И в строке программы вызывающей сбой функция strtok находит пробел в переданной ей строке и пытется его заменить на символ с кодом ноль (для разделения на токены). Но строка-то в ROM лежит, куда записи нет. Вот и вылетает. Общие методические рекомендации: 0) т.н. "венгерская нотация" -- это трэш, аццкий угар и содомия. 1) CamelCase нужен только в тех местах где действительно нужен, скорей это большие проекты где есть трудности с идентификаторами без CamelCase. 2) звёздочку нужно рисовать ближе к переменной, иначе взгляд не цепляется за указатель. 3) добавить в Makefile, если gcc, такие строки: -Wall -Wundef -Wcast-qual -Wpointer-arith -Wcast-align -Wwrite-strings 4) НИКОГДА, никогда не писать код вида printf(variable). За это сжигать нужно. Пиши fputs(variable, stdout), puts(variable), printf("%s", variable). Потому, что в variable могут встретиться проценты ведущие к эксплойтам космических масштабов. 5) Всегда думать, когда const, когда не const. И не делать не const когда не нужно, ибо растратно и чревато казусами. Если очень надо, то можно #define DECONST(v) ((void*)(intptr_t)(v)) -- но это ядерная дубина для очень немолодых коллег. Обычно используется в одном месте в большом проекте. 6) В теле функции выражений тип char x[] = "xxx", const char x[]="..." и для других типов подобного не использовать без надобности, если данные константны, и писать static const char x[]="xxx". Потому, что указатель на такую строку можно куда-то передать, а без static срок жизни указателя кончается по возвращению из функции.
[ZX]