עבור לתוכן

גישה למערך של פוינטרים בC, סיבכתי את עצמי לגמרי.

Featured Replies

פורסם

שלום לכולם,

אני רוצה לרוץ על הנתונים שנמצאים במערך. כתובת המערך נמצא במערך של פוינטרים. זה ניראה ככה:

...
const unsigned char upper_A[25]={0x0C, 0x00, 0x08, 0x00, 0x0E, 0x00, 0x09, 0xC0, 0x09, 0x30, 0x01, 0x18, 0x01, 0x7E, 0x01, 0xF8, 0x09, 0xE0, 0x0F, 0x80, 0x0F, 0x00, 0x0C, 0x00, 0x08}; // Code for char A
const unsigned char upper_B[21]={0x0A, 0x02, 0x08, 0x02, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0xE6, 0x0C, 0xBE, 0x0F, 0x1C, 0x07}; // Code for char B
const unsigned char upper_C[23]={0x0B, 0x00, 0x00, 0xF0, 0x01, 0xF8, 0x03, 0x0C, 0x06, 0x06, 0x0C, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x04, 0x08, 0x0C, 0x04, 0x1E, 0x06}; // Code for char C
const unsigned char upper_D[23]={0x0B, 0x02, 0x08, 0x02, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x06, 0x0C, 0x0C, 0x06, 0xF8, 0x03, 0xF0, 0x01}; // Code for char D...
...
const unsigned char * const characters[]={&space, &exclamation_mark, &double_quotes, &number, &dollar, &percent,
&ampersand, &single_quote, &open_parenthesis, &close_parenthesis, &asterisk, &plus, &comma, &hyphen, &period,
&slash, &number_0,&number_1, &number_2, &number_3, &number_4, &number_5, &number_6, &number_7, &number_8,
&number_9, &colon, &semicolon, &less_than, &equal, &greater_than, &question_mark, &at_symbol ,&upper_A, &upper_B,
&upper_C, &upper_D, &upper_E, &upper_F, &upper_G, &upper_H, &upper_I, &upper_J, &upper_K, &upper_L,
&upper_M, &upper_N, &upper_O, &upper_P, &upper_Q, &upper_R, &upper_S, &upper_T, &upper_U, &upper_V, &upper_W,
&upper_X, &upper_Y, &upper_Z, &opening_bracket, &backslash, &closing_bracket, &circumflex, &underscore,
&grave_accent ,&lower_a, &lower_b, &lower_c, &lower_d, &lower_e, &lower_f, &lower_g, &lower_h, &lower_i,
&lower_j, &lower_k, &lower_l, &lower_m, &lower_n, &lower_o, &lower_p, &lower_q, &lower_r, &lower_s, &lower_t,
&lower_u, &lower_v, &lower_w, &lower_x, &lower_y, &lower_z, &opening_brace, &vertical_bar, &closing_brace, &tilda,
&alef, &bet, &gimel, &dalet, &hei, &vav, &zain, &het, &tet, &yud, &haf_sofit, &haf, &lamed, &mem_sofit, &mem,
&nun_sofit, &nun, &samech, &ayin, &pei_sofit, &pei, &tzadi_sofit, &tzadi, &kuf, &reish, &shin, &taf
};

כתבתי את הפונקציה הבאה:

אני מנסה לכתוב פונקציה שמקבלת ערך מסוג char בודקת שהוא בטווח המתאים (בין 32 ל126 כולל [לבנתיים]) מפחיתה מהערך שלו 32 (עד כה אין לי בעיה). לאחר מכן הפונקציה אמורה לגשת למערך characters ולשלוף את הכתובת של המערך המתאים ולרוץ על הערכים שלו (לבצע בדיקות על ערכם ולשלוח לפונקציה אחרת).

איך בעצם אני ניגש למערך characters ?

void DrawLetter(char Letter)
{
unsigned char *letterPtr;
unsigned char letterLength;

if(Letter>=32 && Letter <=126) //If Letter is legal and in English
Letter=-32; //Remove Letter Offset
letterPtr = &characters+ Letter;
letterLength = *letterPtr;
while(letterPtr-characters[Letter] < letterLength)
{
//CODE
letterPtr++;
}
}

משהו פה לא מסתדר לי, אולי עדיף לגשת למערך characters ע"י האינדקס שלו ?

letterPtr=characters[Letter];

פורסם

מה זה אמור לעשות?

letterPtr = &characters+ Letter;

כי אם זה אמור להיות זהה ל-[characters[Letter, אז זה לא. הקוד המקביל לזה הוא

letterPtr = *(characters+Letter)

בכל מקרה לדעתי עדיף להימנע מלגשת למערכים כאילו הם מצביעים, בדיוק בגלל דברים כאלה. עדיף לגשת למערכים באמצעות אינדקסים כי זה הרבה יותר קריא.

פורסם

מה המטרה של הקוד?

פורסם
  • מחבר

ההסבר הראשון שלי כנראה לא משהו כמו שחשבתי.

בגדול המטרה של הקוד היא להדפיס תווים על תצוגה, אופן ההדפסה לא רלוונטי כרגע. הערכים הנחוצים להדפסה של כל תו נתונים במערכים כפי שניתן לראות בחלק קוד הראשון שהוספתי.

אני רוצה לבנות פונקציה שתדע להדפיס כל אות לפי הנתונים שנמצאים במערך, לכן יצרתי מערך של פוינטרים שמסדרים לי את התווים לפי ערכי הASCII כאשר SPACE מתחיל בערך 0 במקום 32.

אם אקרא לפונקציה כך לדוג':

DrawLetter('A');

ארצה שהפונקציה הנ"ל תשלח לפונקציה אחרת, את כל הערכים שבמערך upper_A.

עריכה:

כרגע עליתי על טעות מפגרת שאולי הייתה הבעיה, רשמתי

Letter=-32 במקום Letter-=32

פורסם

תן לי להבין, space, exlamation_mark, double_quotes וכו' הם פשוט קבועי char שכל אחד מהם מכיל את התו שבשם שלו?

אם כן, אז מה הטעם בכלל במערך characters? הוא פשוט מחזיק מצביעים למספרים מ-32 עד 126.

חוץ מזה, לא כל כך ברור לי למה יש לך הרבה מערכים קבועים שכל אחד עם שם אחר (upper_A,upper_B,upper_C וכו'). הרבה יותר פשוט לעשות מערך דו מימדי (ואז תוכל לגשת אליו באמצעות אינדקס, במקום if או switch/case ענק).

פורסם
  • מחבר

זה היה בדיוק הרעיון, שהוא יחזיק את הכתובת של התווים ככה שיהיה נוח לפנות אליהם.

זה די דומה למערך דו מימדי בלי שכל האיברים בעלי אותו אורך.

עריכה: מערך דו מימדי סתם יבזבז לי מקום בזכרון (שחכתי לציין שהקוד מיועד לרוץ על מיקרו בקר) ולא רציתי לעשות 100 משפטי if/switch case כי יש קשר בין סדר התוים לערכי הASCII.

--------------------------------------------------

כניראה נפל עלי חוסר ריכוז זמני כי עכשיו הצלחתי:

void DrawLetter(char Letter)
{
unsigned char *letterPtr;
unsigned char letterLength;
volatile unsigned char testvar;

if(Letter>=32 && Letter <=126) //If Letter is legal and in English
{
Letter-=32; //Remove Letter Offset
letterPtr=characters[Letter];
testvar=*letterPtr;
}
}

אני רק צריך לולאה בפנים שתקרא לפונקציה שאני רוצה.

תודה רבה לכולם.

פורסם

שוב:

תן לי להבין, space, exlamation_mark, double_quotes וכו' הם פשוט קבועי char שכל אחד מהם מכיל את התו שבשם שלו?

כלומר, איפשהו יש לך את הקוד הזה:

char space = ' ';
char exclamation_mark = '!';
char double_quotes = '\"';

וכן הלאה?

כי אם כן, אז הקוד הזה:

  if(Letter>=32 && Letter <=126)  //If Letter is legal and in English
{
Letter-=32; //Remove Letter Offset
letterPtr=characters[Letter];
testvar=*letterPtr;
}

פשוט עושה:

testvar = Letter;

פורסם
  • מחבר

נכון, קיימים לי בהמשך עוד כ100+ מערכים.

אם נניח שLetter='A'

אז testvar יהיה שקול לupper_a[0] שזה בעצם גם &upper_A

שים לב שכל מערך לא מכיל את ערך התו אלא את הנתונים שיש להעביר לפונקציה מסויימת כדי שהיא תדע לצייר אותו פיקסל אחר פיקסל.

פורסם

אה, אז בסדר. אבל אין סיבה ש-characters יכיל מצביע ל-space, exclamation_mark וכן הלאה. המערכים הם הרי כבר מצביעים, ולכן אתה לא צריך את ה-&.

פורסם

קודם כל, אתה יכול ליצור STRUCT שיכיל מידע על אות - אורך הנחונים הדרושים, והנתונים עצמם.

אחר כך, תיצור מערך שיכיל מצביעים למידע על האותיות.

כדי למצוא מידע על אות, פשוט תיגש למקום המתאים במערך, ותקבל את הפויינטר למידע שלו. את הפוינטר הזה אתה יכול לשלוח לאיזה פונקציה שאתה רוצה כדי להדפיס את האות.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים