|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 6:18 pm
|
Страница 1 от 1
|
[ 11 мнения ] |
|
C въпрос , грешка /предупреждение
| Автор |
Съобщение |
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 11:22 pm Мнения: 3084
|
 C въпрос , грешка /предупреждение
Здравейте, Опитвам се да си сглобя някакво обобщено обработване на менюта на Си, Долният код го компилирам като C++ и като C . В първия случай ми дава грешка "main.cpp|56|error: cannot convert 'const singlefieldstruct* (*)[3]' to 'singlefieldstruct**' in initialization" Във втория случай му издава предупреждение ||=== Build: Release in pm1 (compiler: GNU GCC Compiler) ===| main.c|48|warning: initialization from incompatible pointer type warning: (near initialization for 'line1descriptor.fieldsinlineptrs') [enabled by default]| Изпълнението ми изглежда коректно. Това се случва на редовете отбелязани съсъ звездички. Какво предизвиква тия грешки/предупреждения, какво правя грешно?  |  |  |  | Код: #include <stdio.h> #include <stdlib.h> #include <conio.h>
struct singlefieldstruct { unsigned char debugfieldname[15]; unsigned char mystringnumber,myfieldtype,myfieldcountbytes,myfieldoffset,myfieldmaxblink; };
struct linedescriptorstruct { unsigned char linenamecheck[10];
unsigned char countfieldsinline;
struct singlefieldstruct **fieldsinlineptrs; void (*myloadfunction) (void); void (*mysavefunction) (void); void (*mydisplayfunction) (void);
};
struct menudescriptorstruct { unsigned char linecountsinmenu; struct linedescriptorstruct **linesinmenuPTRS; };
/// MENU 1 /// /// line 1 description const struct singlefieldstruct field1line1={"FieldL1F1:",1,1,1,1,1 }; const struct singlefieldstruct field2line1={"FieldL1F2:",2,3,4,5,6 }; const struct singlefieldstruct field3line1={"FieldL1F3:",1,1,1,1,1 }; const struct singlefieldstruct *line1fieldsPTRS[]= { &field1line1, &field2line1, &field3line1 }; void myline1load(void) {}; void myline1save(void) {}; void myline1display(void) {};
const struct linedescriptorstruct line1descriptor= { "M1line1", 3, &line1fieldsPTRS,///************************************** &myline1load, &myline1save, &myline1display };
/// line 2 description const struct singlefieldstruct field1line2={"FieldL2F1:",1,1,1,1,1 }; const struct singlefieldstruct field2line2={"FieldL2F2:",2,3,4,5,6 }; ///const struct singlefieldstruct field3line2={"FieldL2F3:"1,1,1,1,1 }; const struct singlefieldstruct *line2fieldsPTRS[]= { &field1line2, &field2line2, }; void myline2load(void) {}; void myline2save(void) {}; void myline2display(void) {};
const struct linedescriptorstruct line2descriptor= { "M1line2", 2, &line2fieldsPTRS, ///************************************** &myline2load, &myline2save, &myline2display
};
const struct linedescriptorstruct *menu1linesPTRS[]= { &line1descriptor, &line2descriptor };
const struct menudescriptorstruct mymenu1= { 2, &menu1linesPTRS ;///************************************** };
///#include <conio.h> void proba1menu1(void) { printf("Menu has %d lines\n",mymenu1.linecountsinmenu) ; int aa,bb; for (aa=0;aa<mymenu1.linecountsinmenu;aa++) {
printf("\n%s _contains_ ",mymenu1.linesinmenuPTRS[aa]->linenamecheck);
printf(" %d _fields:\n ", mymenu1.linesinmenuPTRS[aa]->countfieldsinline ); printf("\n") ; for (bb=0;bb<mymenu1.linesinmenuPTRS[aa]->countfieldsinline;bb++) { printf ("%s\n",mymenu1.linesinmenuPTRS[aa]->fieldsinlineptrs[bb]->debugfieldname ); };
}; system("PAUSE"); }
int main() { printf("Hello world!\n"); proba1menu1(); return 0; }
|  |  |  |  |
|
| Чет Дек 17, 2015 12:01 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Проблемът е, че при инициализацията предаваш const променлива към не-const такава. В декларацията на linedescriptorstruct, трябва да направиш singlefieldstruct const.
Също обърни внимание на разликата между: const int*, const int * const, и int const *. В твоя случай май има смисъл и указателя и стойността да са const, ако не смяташ да променяш менюто по време на работа на програмата.
|
| Чет Дек 17, 2015 12:48 pm |
|
 |
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 11:22 pm Мнения: 3084
|
 Re: C въпрос , грешка /предупреждение
не се справих, сложих "const" на
const struct singlefieldstruct **fieldsinlineptrs; struct singlefieldstruct const **fieldsinlineptrs; struct singlefieldstruct ** const fieldsinlineptrs; const struct singlefieldstruct ** const fieldsinlineptrs;
Все тая. Струва ми се ,че трябва да е нещо ,където са звездичките, където се цитират масивите с указатели. Менютата ще са фиксирани,тоест .всички са конст и с инициализиране.
|
| Чет Дек 17, 2015 1:13 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Сега гледам, че едното ти е pointer to pointer, другото array of pointers, което не е един и същи тип.
Коато цяло на пръв поглед не мога да вникна точно в логиката ти (може би и поради липсата на коментари).
|
| Чет Дек 17, 2015 2:02 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Инсталирай си програмката 'cdecl' и после с нея можеш да си тестваш: Също има разни правила, като четене отзад-напред и спираловидно: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.htmlhttp://c-faq.com/decl/spiral.anderson.htmlНе съм вниквал в логиката, но като се оправят типовете се компилира и при изпълнение извежда това на екрана: За да се компилира са необходими следните промени (махнал съм и Уиндоус специфичните неща, за да тествам):  |  |  |  | Код: --- stef.orig 2015-12-17 11:09:01.992775465 +0000 +++ stef.c 2015-12-17 11:25:58.480752221 +0000 @@ -1,6 +1,5 @@ #include <stdio.h> #include <stdlib.h> -#include <conio.h> struct singlefieldstruct { @@ -14,7 +13,7 @@ unsigned char countfieldsinline; - struct singlefieldstruct **fieldsinlineptrs; + const struct singlefieldstruct* (*fieldsinlineptrs)[]; void (*myloadfunction) (void); void (*mysavefunction) (void); void (*mydisplayfunction) (void); @@ -24,7 +23,7 @@ struct menudescriptorstruct { unsigned char linecountsinmenu; -struct linedescriptorstruct **linesinmenuPTRS; +const struct linedescriptorstruct* (*linesinmenuPTRS)[]; }; /// MENU 1 /// @@ -82,7 +81,7 @@ const struct menudescriptorstruct mymenu1= { 2, -&menu1linesPTRS ;///************************************** +&menu1linesPTRS ///************************************** }; @@ -96,17 +95,16 @@ { - printf("\n%s _contains_ ",mymenu1.linesinmenuPTRS[aa]->linenamecheck); + printf("\n%s _contains_ ",(*mymenu1.linesinmenuPTRS)[aa]->linenamecheck); - printf(" %d _fields:\n ", mymenu1.linesinmenuPTRS[aa]->countfieldsinline ); + printf(" %d _fields:\n ", (*mymenu1.linesinmenuPTRS)[aa]->countfieldsinline ); printf("\n") ; - for (bb=0;bb<mymenu1.linesinmenuPTRS[aa]->countfieldsinline;bb++) + for (bb=0;bb<(*mymenu1.linesinmenuPTRS)[aa]->countfieldsinline;bb++) { - printf ("%s\n",mymenu1.linesinmenuPTRS[aa]->fieldsinlineptrs[bb]->debugfieldname ); + printf ("%s\n",(*(*mymenu1.linesinmenuPTRS)[aa]->fieldsinlineptrs)[bb]->debugfieldname ); }; }; -system("PAUSE"); }
|  |  |  |  |
Ето и целия код:  |  |  |  | Код: #include <stdio.h> #include <stdlib.h>
struct singlefieldstruct { unsigned char debugfieldname[15]; unsigned char mystringnumber,myfieldtype,myfieldcountbytes,myfieldoffset,myfieldmaxblink; };
struct linedescriptorstruct { unsigned char linenamecheck[10];
unsigned char countfieldsinline;
const struct singlefieldstruct* (*fieldsinlineptrs)[]; void (*myloadfunction) (void); void (*mysavefunction) (void); void (*mydisplayfunction) (void);
};
struct menudescriptorstruct { unsigned char linecountsinmenu; const struct linedescriptorstruct* (*linesinmenuPTRS)[]; };
/// MENU 1 /// /// line 1 description const struct singlefieldstruct field1line1={"FieldL1F1:",1,1,1,1,1 }; const struct singlefieldstruct field2line1={"FieldL1F2:",2,3,4,5,6 }; const struct singlefieldstruct field3line1={"FieldL1F3:",1,1,1,1,1 }; const struct singlefieldstruct *line1fieldsPTRS[]= { &field1line1, &field2line1, &field3line1 }; void myline1load(void) {}; void myline1save(void) {}; void myline1display(void) {};
const struct linedescriptorstruct line1descriptor= { "M1line1", 3, &line1fieldsPTRS,///************************************** &myline1load, &myline1save, &myline1display };
/// line 2 description const struct singlefieldstruct field1line2={"FieldL2F1:",1,1,1,1,1 }; const struct singlefieldstruct field2line2={"FieldL2F2:",2,3,4,5,6 }; ///const struct singlefieldstruct field3line2={"FieldL2F3:"1,1,1,1,1 }; const struct singlefieldstruct *line2fieldsPTRS[]= { &field1line2, &field2line2, }; void myline2load(void) {}; void myline2save(void) {}; void myline2display(void) {};
const struct linedescriptorstruct line2descriptor= { "M1line2", 2, &line2fieldsPTRS, ///************************************** &myline2load, &myline2save, &myline2display
};
const struct linedescriptorstruct *menu1linesPTRS[]= { &line1descriptor, &line2descriptor };
const struct menudescriptorstruct mymenu1= { 2, &menu1linesPTRS ///************************************** };
///#include <conio.h> void proba1menu1(void) { printf("Menu has %d lines\n",mymenu1.linecountsinmenu) ; int aa,bb; for (aa=0;aa<mymenu1.linecountsinmenu;aa++) {
printf("\n%s _contains_ ",(*mymenu1.linesinmenuPTRS)[aa]->linenamecheck);
printf(" %d _fields:\n ", (*mymenu1.linesinmenuPTRS)[aa]->countfieldsinline ); printf("\n") ; for (bb=0;bb<(*mymenu1.linesinmenuPTRS)[aa]->countfieldsinline;bb++) { printf ("%s\n",(*(*mymenu1.linesinmenuPTRS)[aa]->fieldsinlineptrs)[bb]->debugfieldname ); };
}; }
int main() { printf("Hello world!\n"); proba1menu1(); return 0; }
|  |  |  |  |
|
| Чет Дек 17, 2015 2:29 pm |
|
 |
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 11:22 pm Мнения: 3084
|
 Re: C въпрос , грешка /предупреждение
Благодаря много Радолине, Компилира се на Си, много има да чета докато го схвана , особено това printf("\n%s _contains_ ",(*mymenu1.linesinmenuPTRS)[aa]->linenamecheck); Не ми е ясно дори как се назовава тая скоба със звездичка. Опитах и следното: Съответно получих предупреждение: c:\work\probac\pm1\main.c|271|warning: assignment discards 'const' qualifier from pointer target type [enabled by default]| Отделно - от лшбопитсвто пуснах компилация като Си++. Продължава да дава грешки, въпреки корекциите. Сигурно още четене 
|
| Чет Дек 17, 2015 4:38 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Това си е оператора * - pointer dereference. С него указва, че се интересуваш се от мястото към което сочи указателя, а не от стойността на самия указател. Скобите са като при всички други операции, за да укажеш приоритетите. Искаме първо на направим dereference (т.е да вземем на където сочи указателя) и чак след това да приложим оператора [] за да вземем елемент от масива. Членът linesinmenuPTRS на структурата mymeny1 ти е "указател към масив от указатели към структури от типа linedescriptorstruct". Ето нещата едно по едно: mymenu1 тип: структура от тип menudescriptorstruct mymenu1.linesinmenuPTRS елемента linesinmenuPTRS от структурата mymenu1 оператор: . достъп до член на структура тип: указател към масив от указатели към linedescriptorstruct *mymenu1.linesinmenuPTRS - накъдето сочи linesinmenuPTRS оператор: * pointer dereference тип: масив от указатели към структури от типа linedescriptorstruct (*mymenu1.linesinmenuPTRS)[aa] - елемент аа от въпросния масив оператор: [] достъп до елемент от масив тип: указател към структура от типа inedescriptorstruct (*mymenu1.linesinmenuPTRS)[aa]->linenamecheck - членът linenamecheck на структурата, към която сочи указателят (*mymenu1.linesinmenuPTRS)[aa] оператор: -> достъп до член на структура, чрез указател тип: масив от unsigned char Ами то си ти казва точно за какво те предупреждава - mymenu1 ти е декларирано const, a ти правиш не-const указател към него, чрез който вече можеш да го модифицираш. C++ някой по-компетентен да каже 
|
| Чет Дек 17, 2015 5:55 pm |
|
 |
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 11:22 pm Мнения: 3084
|
 Re: C въпрос , грешка /предупреждение
Благодаря за разясненията! Ще ги обмислям малко по-нататък и сигурно пак ще питам. Утреще пробвам с "const" const struct menudescriptorstruct* menuwork;
|
| Чет Дек 17, 2015 11:20 pm |
|
 |
|
stefan63
Ранг: Форумен бог
Регистриран на: Вто Фев 07, 2012 11:22 pm Мнения: 3084
|
 Re: C въпрос , грешка /предупреждение
Обаче цял ден ме терзае начина ,по който реши проблема с масивите от указатели - Тая дума "const" стои много странно по средата на дефиницията, а без нея не става.
|
| Чет Дек 17, 2015 11:31 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Да, ако добавиш този const би трябвало да ти изчезне warning-a.
|
| Пет Дек 18, 2015 12:08 am |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: C въпрос , грешка /предупреждение
Предполагам, че по средата на дефиницията на структурата имаш предвид. Защо да е странно? Тя се отнася в случая само за елемента fieldsinlineptrs. По принцип може да махнеш всички const-ове и нещата ще си работят. Ползата от тях е, че ако си казал, че нещо не трябва да се променя, а после някъде из кода се опиташ да го промениш компилатора веднага ще ти изпищи. Съответно ще си хванеш грешката много по-рано и няма да загубиш дни и нощи в дебъгване на мистериозен проблем. Също евентуално може и да помогне на компилатора да оптимизира кода или къде се съхраняват променливите в някои случаи.
|
| Пет Дек 18, 2015 12:16 am |
|
|
|
Страница 1 от 1
|
[ 11 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 0 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|