הצבת ערך ב-struct (שפת C)
-
נתון קוד
#include <iostream> struct Grade { char profession[10]; int percent; }; struct Student { char name[10]; char email[20]; Grade grdArr[10]; }; int main() { Student studentsArr[5]; Student* stdPtr = studentsArr; *stdPtr->email ='1234'; }
2 שאלות:
א. שורה 18 מאפשרת הצבת החל מ 0 תוים ועד 4. בכל מקרה יוצב התו האחרון (במקרה הזה 4).
למה המערכת מאפשרת יותר מתו אחד במצביע מסוג CHAR בודד?ב. איך מציבים את האימייל כולו בצורה תקינה?
תודה רבה!
-
@yyy
א. char email[20] זה לא תו בודד, אלא מערך של 20 תווים
ב. שרשרת של תווים, מה שנקרא סטרינג string עושים עם מרכאות כפולות
ג. כשאתה שם מרכאה בודדת, זה תו. בC++ אם יש כמה תווים במרכאה בודדת זה מומר לint, כלומר לא 1234 אלא מספר מפחיד (825373492) שיוצא בינארית מהערכי התווים של 1234 (אין לי מושג איך..).
ד. אני לא מכיר את C, אני לא יודע איך מציבים מחרזות במשתנה של מערך תווים, או כל סוג אחר. -
בנוסף למה ש@dovid כתב:
- בכתיבה ב-++/C צריך תמיד להיות מודע לדברים קטנוניים כמו איפה הזכרון מוקצה ב-stack או ב-heap, והאם יש לך מצביע לזכרון או reference לזכרון וכו'
- ההצהרה
char email[20]
אומר להקצות אזור של 20 בייטים בתוך ה-struct, כנ"ל ההצהרה מקצה זכרון פנוי עבור 5X40 בייטים על ה-stack. - המחרוזת
"1234"
(אחרי התיקון למרכאות כפולות) מחזיר מצביע לזכרון שמוקצה בצורה סטטית באזור אחר לגמרי של הזכרון (זה מוקצה על ידי מערכת ההפעלה כאשר היא טוענת את הבינארי) - כדי להעתיק את התוכן של הזכרון הזה לתוך 20 הבייטים המוקצים ב-stack צריך להעתיק אותם (
memcpy
או משהו דומה (דוגמה)) ולא מספיק השמה פשוטה, כי משתנה של מחרוזת זה בעצם* char
ולכן ההשמה שניסית לעשות הוא השמה של הפויינטר ולא של היעד של הפויינטר - אפשרות פשוטה יותר זה להגדיר את שדה ה-email כ-
* char
במקום[]char
ואז אפשר לעשות השמה פשוטה (אומנם אתה מקבל אזהרה מהקופיילר, אבל זה מתקמפל ועובד) - בשורה 18 הכוכבית בתחילת השורה לא נכונה,
stdPtr->email
מחזיר משתנה מסוג* char
(כי משתנה מסוג מערך הוא תמיד מצביע על האיבר הראשון), ואם תשים*
לפני קיבלת את היעד של הפויינטר שזה ה-char
הראשון של האימייל - סתם נקודה לא חשובה, זה לא שפת C אלא ++C, הקוד לא תקין ב-C (שם צריך לכתוב
struct Student
בכל מקום במקום רקStudent
)
הנה דוגמה שעובדת (אומנם עם אזהרה)
וזה בלי אזהרה: https://godbolt.org/z/1TGxrPe1P