|
Указатель на строку в структуре, или даже указатель на указатель |
|
|
|
Aug 3 2011, 11:18
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Нужна помощь опытных специалистов. Код такой: Код typedef struct { int x_numicons; int y_numicons; int iconnumber[10]; } imenu_icons_t;
typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; char *menu_text[10]; } imenu_t;
imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};
imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};
int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; char *ptr;
// В функции показано не все, поэтому пусть не смущает ее бессмысленность
for(i = 0; i < entries; i++) { ptr = (char *)pmenu->menu_text[i]; }
return current; }
unsigned char ic;
void main(void) { ic = icon_menu(&mainmenu); } беспокоит строка: ptr = (char *)pmenu->menu_text[i]; так как сейчас она указывает не туда куда хотелось бы. Вопрос в том как это правильно сделать, т.е. чтобы указатель указывал на строку?
Сообщение отредактировал 011119xx - Aug 3 2011, 11:20
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 29)
|
Aug 3 2011, 11:39
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(011119xx @ Aug 3 2011, 15:18)  как это правильно сделать, т.е. чтобы указатель указывал на строку? Скорее всего, так: Код imenu_t mainmenu = {&main_idle, &main_active, &main_icon, {main_text[0], main_text[2], main_text[3], main_text[4], main_text[5], main_text[6], main_text[7], main_text[8], main_text[9] } };
|
|
|
|
|
Aug 3 2011, 11:40
|

Местный
  
Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631

|
Лучше работать с указателем на массив указателей на строки. CODE typedef struct {
u8 QtyString;
u8 **pStr;
} MENU_PageText;
const u8 *MENU_TEXT_RU[] =
{
"выаопвылаопвыо",
"ывалдоплвыоапло",
"ывавыавыоапио"
};
..........
..........
const MENU_PageText PagesText[] =
{
{0x3,MENU_TEXT_EN},
{0x3, MENU_TEXT_DE},
{0x3,MENU_TEXT_IT},
{0x3, MENU_TEXT_RU}
};
Сообщение отредактировал ISK2010 - Aug 3 2011, 11:46
|
|
|
|
|
Aug 3 2011, 13:02
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(ISK2010 @ Aug 3 2011, 14:40)  Лучше работать с указателем на массив указателей на строки. Не факт, но инициализировать меню удобрее с помощью макросов, типа: Код STATE ( Abort , "Aborted !" , "Entnahme abgebrochen!" ,"Остановлено!" , CLR+STN+OLD+SSS+SLB ) STATE ( Finish , "Finished:" , "Beendet:" ,"Закончено:" , CLR+STN+OLD+SSS+SLB )
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Aug 4 2011, 10:27
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Проблема решается так: Код typedef struct { int x_numicons; int y_numicons; int iconnumber[10]; } imenu_icons_t;
typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; char *menu_text[10]; } imenu_t;
imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};
imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};
const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};
void print(char *text) { char c;
while(c = *(text++)) { // Печать символа } }
int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; char **ptr = (char *)pmenu->menu_text[0];
for(i = 0; i < entries; i++) { print(*(ptr + i)); }
return current; }
unsigned char ic;
void main(void) { ic = icon_menu(&mainmenu); }
|
|
|
|
|
Aug 4 2011, 11:05
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(011119xx @ Aug 4 2011, 14:27)  Проблема решается так "Кривое" решение. Корректнее это сделать так: Код ... typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; char **menu_text; } imenu_t; ..... const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};
..... int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; char **ptr = pmenu->menu_text;
.... } ....
|
|
|
|
|
Aug 5 2011, 02:45
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Keil ваш вариант не устраивает. А вот такой устраивает: Код ... typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; const char **menu_text; } imenu_t; ..... const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};
..... int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; const char **ptr = pmenu->menu_text;
for(i = 0; i < entries; i++) { print((char *)(ptr + i)); } .... } ....
Сообщение отредактировал 011119xx - Aug 5 2011, 02:46
|
|
|
|
|
Aug 5 2011, 16:23
|
self made
   
Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795

|
Цитата(011119xx @ Aug 4 2011, 06:27)  Проблема решается так: Подтверждаю, кривое, если не сказать кривейшее. Массив на 10 элементов, используется и инициализируется только один. Используется причем неправильно. Код char **ptr = (char *)pmenu->menu_text[0]; В этой строке вам ничего глаз не режет?
|
|
|
|
|
Aug 8 2011, 02:44
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Окончательный вариант принятый к использованию: Код ... typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; const char **menu_text; } imenu_t; ..... const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};
..... int icon_menu(imenu_t *pmenu) { unsigned char i, entries;
.... for(i = 0; i < entries; i++) { print((char *)pmenu->menu_text[current]); } .... } ....
|
|
|
|
|
Aug 8 2011, 07:50
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(011119xx @ Aug 8 2011, 06:44)  Окончательный вариант принятый к использованию: Код .... for(i = 0; i < entries; i++) { print((char *)pmenu->menu_text[current]); } .... } Просто глаз радуется, глядя на цикл, в котором индекс никак не используется в теле.
|
|
|
|
|
Aug 8 2011, 08:33
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Цитата(sergeeff @ Aug 8 2011, 13:50)  Просто глаз радуется, глядя на цикл, в котором индекс никак не используется в теле. Так нормально? Код .... for(i = 0; i < entries; i++) { print((char *)pmenu->menu_text[i]); } .... Цитата(XVR @ Aug 8 2011, 13:46)  Можно просто написать print(pmenu->menu_text[current]); Keil на такое ругается так как print объявлена: void print(char *str);
|
|
|
|
|
Aug 8 2011, 08:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(011119xx @ Aug 8 2011, 12:33)  Так нормально? Код .... for(i = 0; i < entries; i++) { print((char *)pmenu->menu_text[i]); } .... Keil на такое ругается так как print объявлена: void print(char *str);Вам лучше знать, нормально это или нет. Вы же автор кода. Объявите функцию print: Код void print(const char *str); Тогда она будет без проблем вызываться с const и не const фактическими переменными.
|
|
|
|
|
Aug 8 2011, 16:37
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(sergeeff @ Aug 8 2011, 16:17)  Это в Канаде, наверное нельзя (может религия не позволяет), а в С можно. Себе тестик в Visual Studio или чем-то другом напишите - увидите. Написал: Код char* func(char* p) { return p; }
const char *gl;
char* func2() { return func(gl); } Цитата C:\!t>gcc-4.exe -c t.c t.c: In function 'func2': t.c:10: warning: passing argument 1 of 'func' discards qualifiers from pointer target type Так что и в С не очень можно (но если очень хочется, то можно - это все же warning, а не error)
|
|
|
|
|
Aug 9 2011, 05:06
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Код typedef struct { int x_numicons; int y_numicons; int iconnumber[10]; } imenu_icons_t;
typedef const char *imenu_text_t[10];
typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; imenu_text_t *menu_text; } imenu_t;
imenu_icons_t main_icon = {1, 1, {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
imenu_icons_t main_idle = {10, 1, {12, 13, 14, 15, 16, 17, 18, 19, 20, 21}};
imenu_icons_t main_active = {10, 1, {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}};
const char * main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, &main_text};
int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; char *ptr;
// Â ôóíêöèè ïîêàçàíî íå âñå, ïîýòîìó ïóñòü íå ñìóùàåò åå áåññìûñëåííîñòü
for(i = 0; i < entries; i++) { ptr = (char *)pmenu->menu_text[i]; }
return current; }
unsigned char ic;
void xmain(void) { ic = icon_menu(&mainmenu); }
|
|
|
|
|
Aug 9 2011, 13:14
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(011119xx @ Aug 9 2011, 06:52)  Вы Keil к Visual Studio подключили? Если так, то научите и меня пожалуйста. А по сути религии могу сказать так: на один и тот же весьма простой исходный текст Keil выдает разные сообщения об ошибках и предупреждениях, если компилировать под С51 и ARM. Скажем, если под С51 его все устраивает, то под ARM уже находит ошибки. 1. Когда я упоминал Visual studio, соответственно речь шла о семействе компиляторов Microsoft. 2. Никто не запрещает вам открыть новый проект в Visual studio, основанный на make, и вообще делать все что хочешь (в смысле вызывать любые компиляторы, линкеры и т.п.). Вот с синхронизацией ошибок в output-окне и editor'e будут проблемы, это да. 3. Если хочется, то можно загрузить бесплатно пакет Visual Studio 2008/2010 SDK и наваять оболочку под себя.
|
|
|
|
|
Jun 8 2012, 06:34
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Снова возвращаюсь к данной теме, так как потребовалось усложнить интерфейс введением поддержки 2-х языков. Соответственно, код используемый ранее требует доработки: Код ... typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; const char **menu_text; } imenu_t; ..... const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};
..... int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i; const char **ptr = pmenu->menu_text;
for(i = 0; i < entries; i++) { print((char *)(ptr + i)); } .... } .... В первую очередь это: Код const char *main_text[10] = {"STR1", "STR2", "STR3", "STR4", "STR5", "STR6", "STR7", "STR8", "STR9", "STR10"}; меняю на это: Код const char *main_text[2][10] = {{"STR1_EN", "STR2_EN", "STR3_EN", "STR4_EN", "STR5_EN", "STR6_EN", "STR7_EN", "STR8_EN", "STR9_EN", "STR10_EN"}, {"STR1_RU", "STR2_RU", "STR3_RU", "STR4_RU", "STR5_RU", "STR6_RU", "STR7_RU", "STR8_RU", "STR9_RU", "STR10_RU"}}; А далее в общем-то запутался. По идее вот это: Код typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; const char **menu_text; } imenu_t; надо тоже менять, правда не пойму как. Функцию, использующую строки меняю на: Код int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i, language; const char **ptr = pmenu->menu_text; //нужно править и как-то использовать language
for(i = 0; i < entries; i++) { print((char *)(ptr + i)); //нужно править и как-то использовать language } .... } Прошу подсказки специалистов как правильно сделать.
|
|
|
|
|
Jun 8 2012, 06:53
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(sergeeff @ Aug 9 2011, 17:14)  2. Никто не запрещает вам открыть новый проект в Visual studio, основанный на make, и вообще делать все что хочешь (в смысле вызывать любые компиляторы, линкеры и т.п.). Вот с синхронизацией ошибок в output-окне и editor'e будут проблемы, это да. Проблемы с форматом вывода решаемыОднако, поработав в этой вашей студии, сакрального смысла не нашел. Это так, в порядке оффтопа. А насчет предупреждения - это просто несовпадение типов. И это не ошибка, а именно предупреждение на всякий случай, чтобы заострить внимание. Вот если объявленную константой строку попытаться изменить - тогда будет уже явная ошибка. Цитата(011119xx @ Jun 8 2012, 10:34)  Прошу подсказки специалистов как правильно сделать. Сделать два отдельных массива адресов сообщений, а в функцию передавать адрес нужного (в зависимости от языка) и номер сообщения. Если я правильно понял задачу.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jun 8 2012, 09:32
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Цитата(MrYuran @ Jun 8 2012, 11:53)  Сделать два отдельных массива адресов сообщений, а в функцию передавать адрес нужного (в зависимости от языка) и номер сообщения. Такой вариант имеет право на жизнь, но мне не подходит. Адрес нужного (в зависимости от языка) и номер сообщения нужно определять в функции Код int icon_menu(imenu_t *pmenu) . И я знаю, что сделать это можно, но пока не могу сообразить.
|
|
|
|
|
Jun 8 2012, 10:49
|

Местный
  
Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544

|
Работает вот так: Код int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i, language = 1; const char **ptr = pmenu->menu_text;
for(i = 0; i < entries; i++) { print((char *)(*(ptr + i + language * entries))); } .... } но хотелось бы избавиться от локального указателя const char **ptr Немного криво, но работает так: Код int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i, language = 1;
for(i = 0; i < entries; i++) { print((char *)(*(&pmenu->menu_text[i + language * entries]))); } .... }
|
|
|
|
|
Jun 9 2012, 11:33
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Код typedef struct { imenu_icons_t *menu_idle; imenu_icons_t *menu_active; imenu_icons_t *menu_icon; const char *(*menu_text)[10]; } imenu_t;
const char *main_text[2][10] = {{"STR1_EN", "STR2_EN", "STR3_EN", "STR4_EN", "STR5_EN", "STR6_EN", "STR7_EN", "STR8_EN", "STR9_EN", "STR10_EN"}, {"STR1_RU", "STR2_RU", "STR3_RU", "STR4_RU", "STR5_RU", "STR6_RU", "STR7_RU", "STR8_RU", "STR9_RU", "STR10_RU"}};
imenu_t mainmenu = {&main_idle, &main_active, &main_icon, main_text};
void print(const char*);
int icon_menu(imenu_t *pmenu) { unsigned char current = 0, i, language; const char **ptr = pmenu->menu_text[language];
for(i = 0; i < entries; i++) { print(ptr[i]); } .... } Или сразу - Код print(pmenu->menu_text[language][i]);
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|