עבור לתוכן
View in the app

A better way to browse. Learn more.

HWzone

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

שאלה ב- C++

Featured Replies

פורסם

1) מה הדרך הכי יעילה (מבחינת זמן ריצה) להפוך char ל-std::string?

2) האם יש אובייקט "כללי" ב-c++? משהו כמו Object ב-Java?

אם כן אז יש לו פונקציה שדומה ל-toString כדי שאוכל להפוך אותו ל-string?

תודה ושנה אזרחית טובה!

:xyxthumbs:

פורסם

1. יש פורום לשפות תכנות עילית. הועבר.

2. באמצעות הבנאי של string.

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

4. אין ב-++C פונקציה סטנדרטית להפוך אובייקט למחרוזת. אם אתה רוצה להיות מסוגל להדפיס את האובייקט, אתה יכול להגדיר את האופרטור >> של cout להיות מסוגל להדפיס אותו, כמו בדוגמה כאן:

http://www.codeproject.com/KB/cpp/cfraction.aspx?fid=15432&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=10

פורסם
  • מחבר

אז אם האובייקט הכללי הזה הוא הוא בטוח char או string אז אפשר יהיה לעשות לו פשוט cout?

ואתה בטוח שיש ל-string קונסטרקטור מ-char?

הייתי בודק בעצמי אבל כרגע אין לי IDE של C++ על המחשב.. עוד מעט זה יסיים להוריד...

פורסם

ל-string יש constructor מ-char* אל תדאג. מצד שני הוא מבצע הקצת זכרון דינמית, ולכן תלוי במקרה שלך אבל זה לא בהכרח הדרך היעילה ביותר.

אכן ניתן להדפיס עם cout כל char* ו-string. אם אתה רוצה להדפיס Unicode (כלומר wstring או wchar_t*) אז צריך להשתמש ב-wcout.

לגבי נושא הירושה, יש צורך בהבהרה:

ב-C++ בפירוש אין מחלקה שכולם יורשים ממנה, וזו פשוט לא חלק מהפילוסופיה של השפה. הגישה של C++ אומרת שאתה לא משלם על מה שאתה לא צריך, או במילים אחרות: אם רוצים, צריך שאפשר יהיה לייצר עם מחלקות קוד יעיל כמו קוד ללא מחלקות. אם כל האובייקטים היו יורשים מ-"object" ולכולם היתה מתודה וירטואלית של ToString, אז כולם היו משלמים את המחיר, מעבר למה שצריך קוד C רגיל.

בנוסף, קיום מחלקה שכולם יורשים ממנה נקרא לפעמים cosmic hierarchy וזה נחשב לרוב תכנון גרוע ב-C++ עקב הבעיות שהוא מייצר.

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

פורסם
  • מחבר

הקוד הבא גרם להדפסה של התו 'a' ולאחריו כל מיני שטויות.


char c = 'a';
string s(&c);
cout << s << endl;

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

אשמח להצעה אחרת

עריכה:


void* c;
c = new char('a');
cout << *c << endl;

לא מתקמפל. ואם אני מנסה להדפיס את c אז זה פשוט מדפיס כתובת.

אין דרך לפתור את זה? אפשר להניח ש-c מצביע ל-string או ל-char.

פורסם

אחר כך אפשר באמצעות casting להמיר אותו חזרה למה שאתה רוצה.

אי אפשר לעשות dereference ל-*void, כי אין לקומפיילר טיפוס להמיר אליו.

פורסם

הקוד הבא גרם להדפסה של התו 'a' ולאחריו כל מיני שטויות.

כדי שהבנאי של string מתוך char* יעבוד, המחרוזת חייבת להיות null-terminated (כלומר להסתיים ב-0\). במקרה שלך זה לא מתקיים כי אחרי הזכרון שהוקצה לתו a יש זבל אקראי. כדי שזה יעבוד תצטרך להגדיר משהו כמו:


char s[2]={'a','\0'};
string(s);


char c = 'a';
string s(&c);
cout << s << endl;

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

אשמח להצעה אחרת


void* c;
c = new char('a');
cout << *c << endl;

לא מתקמפל. ואם אני מנסה להדפיס את c אז זה פשוט מדפיס כתובת.

אין דרך לפתור את זה? אפשר להניח ש-c מצביע ל-string או ל-char.

אתה לא יכול לעשות dereference ל-*void. הביטוי c* חסר משמעות. על מנת שיהיה בעל משמעות, אתה צריך לעשות casting מפורש:



cout << *(char*)c << endl;

פורסם
  • מחבר

אוקיי.

תודה רבה על העזרה!

פורסם

כמה הערות חשובות מאוד של הקוד של QttP: (מה שהוא אמר זה נכון בגדול):

ניתן לבנות string מתוך char* שהוא NULL-terminated שזה ה-string הסטנדרטי ב-C. ובגלל שהוא הסטנדרטי, לא צריך לעבוד קשה כדי ליצור אותו, הקומפיילר יעשה זאת בשבילך.


char s1[] = "a";
char s2[2] = {'a', '\0'}; /* effectively the same as s1 */
const char *s3 = "a"; /* not the same as s2 but more commond then s2 */
string(s1);
string(s2);
string(s3);

המרה מ-void*:

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

באופן כללי, עדיף להמיר ל-const char* אם אין צורך בשינוי המחרוזת, כי אתה לא יודע מאיפה הגיע המצביע, ומה בדיוק עושה הפונקציה שקוראים לה.


void *p = "hello world"; /* allowed in C, not in C++ */
const void *p2 = (const void *)"hello world"; /* allowed in C++ */
...
...
char *s = (char*)p;
s[0] = 'j'; /* OH NOES! We are writing on constant data memory area! This is an error! */
...
char *s2= (char*)p2; /* yes, this is allowed even in C++ */
s2[0] = 'j';/* ERROR! */

פורסם

עוד הערה קטנה אחרונה: כשמבצעים casting ב-++C, נהוג להשתמש באופרטור המתאימים של ++C, ולא בהמרה ה"רגילה" של C. כלומר, להשתמש באחד מהאופרטורים const_cast, static_cast, dynamic_cast ו-reinterpret_cast.

במקרה הספציפי הזה, למיטב זכרוני, צריך להשתמש ב-static_cast.

פורסם

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

הנה דוגמה על לינוקס:



#include <stdio.h>

int main()
{
char* s = "Pello World";

s[0] = 'H';
puts(s);

return 0;
}

לאחר קומפילצה והרצה נקבל:


$ gcc write_const.c -o wrc
$ ./wrc
Segmentation fault

ארכיון

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

דיונים חדשים

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.