עבור לתוכן
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,H והפקודה makefile בunix.

Featured Replies

פורסם

חברים,

לימדו אותנו לעשות את הפקודה makefile שכאילו מקשרת בין כמה קבצי C וH שרוצים ואז אפשר להשתמש נניח בקובץ C1.c בפונקציה שכתובה בH1.h

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

אני צריך ליצור קובץ H וליצור קובץ C שמשתמש בפונקציות שכתובות בH.

אז השאלה שלי היא כזאת:

כיצד בdev C++ אני יוצר קובץ H עם הפונקציות הרלוונטיות? (אם אפשר לתת מבנה כללי של הקובץ, איפה ההכרזות על הפונקציות, איפה המימושים של הפונקציות , היכן לרשום הכרזות על קבצי H אחרים שאני רוצה להשתמש בהם? (למשל Stdio או math או קובץ H2.h שאני יצרתי למשל))

ואיך אחרי שיש לי קובץ C וקובץ H אני מקשר ביניהם דרך המייקפייל? ד"א אם בהאדר שלי H1.h אני כולל את הספריות Stdio.h math.h וכו' ואלה הספריות שאני משתמש בהם בתכנית, מסספיק לי בקובץ C להכריז בלבד

#include <H1.h>

?

או שעדיין אצטרך לרשום את כולם?

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

פורסם

makefile זו לא פקודה, זה פורמט של קובץ. לפקודה שמשתמשת בו קוראים make.

ה-makefile הוא פשוט רשימה של "יעדים" (targets), שלכל אחד מהם כתוב באיזה יעדים הוא תלוי, ומה הפקודות שצריך להריץ על מנת להגיע ליעד הזה.

ב-makefile בד"כ לא מתייחסים לקובצי h, כי מתייחסים אליהם רק בזמן הקומפילציה (ולא בכל הבנייה).

אני לא מבין, לא למדת איך בדיוק עושים את ההפרדה בין קובץ c וקובץ h?

בתוך קובץ ה-h אתה רק מצהיר על פונקציות (בלי לכלול מימוש), על מנת שיוכלו להשתמש בהן. כל מי שעושה include לקובץ ה-h שלך בעצם יידע שהפונקציות האלה קיימות.

הסדר של הפונקציות בתוך הקובץ לא חשוב, כמובן (כי הפונקציות לא מתייחסות אחת לשנייה).

כשאתה עושה include לקובץ כלשהו, אז הקומפיילר בעצם "מדביק" את הקובץ הזה בתוך הקובץ שעשית include לתוכו. פעולת ה-include היא רקורסיבית - אם עשית include ל-a.h, ובתוך a.h עשית include ל-b.h, אז זה כאילו עשית include גם ל-b.h.

בגלל זה, פחות מומלץ לעשות include מקובץ h לקובץ h אחר, אלא אם אתה צריך. מה הכוונה? אם יש לך קבצים a.h ו-a.c בהם אתה מגדיר ומממש פונקציות שתלויות בכל מיני פונקציות שמוגדרות ב-stdio.h, אז עדיף שה-include ל-stdio תהיה בתוך a.c, ולא ב-a.h. הסיבה לכך היא שאתה לא רוצה שכל מי שיעשה include ל-a.h יקבל גם את stdio.h (כי לא בטוח שמי שרוצה להשתמש בפונקציות מ-a בכלל צריך פונקציות מ-stdio). כמובן, יש מקרים בהם אתה חייב (לדוגמה, אם stdio מכיל כל מיני הגדרות שאתה חייב להכיר על מנת להשתמש בפונקציות ב-a.h).

חוץ מזה, חשוב לזכור לכלול include guard בקובץ h שלך.

נ.ב.: כשאתה עושה אינקלוד לקובץ מקומי (כמו במקרה של H1.h) אתה צריך להשתמש במרכאות במקום <>, כלומר:

#include "H1.h"

משתמשים ב-<> עבור אינקלוד של חבילות חיצוניות, כמו stdio.h.

פורסם
  • מחבר

אוקיי, הבנתי אותך.

אז את המימוש של הפונקציות שהכרזתי עליהם בH אני כותב בC?

לא הפואנטה שיהיה המימוש גם בH ואז בC פשוט לקרוא להם בmain?

זהו, לא הבנתי כל כך איך לעשות את ההפרדה בין קובץ C לבין קובץ H, או יותר נכון איך ליצור קובץ H בכלל.

הקובץ H שיצרתי, הוא צריך להיות בתיקייה מסוימת כדי שהתכנית תוכל לקרוא ממנו?

פורסם

אוקיי, הבנתי אותך.

אז את המימוש של הפונקציות שהכרזתי עליהם בH אני כותב בC?

כן.

לא הפואנטה שיהיה המימוש גם בH ואז בC פשוט לקרוא להם בmain?

לא הבנתי את השאלה. בכל מקרה, את המימוש שמים בקובץ c. הלינקר (linker) דואג אחר כך לחבר בין הפונקציות שנמצאות בתוך קבצי ה-c השונים.

זהו, לא הבנתי כל כך איך לעשות את ההפרדה בין קובץ C לבין קובץ H, או יותר נכון איך ליצור קובץ H בכלל.

הקובץ H שיצרתי, הוא צריך להיות בתיקייה מסוימת כדי שהתכנית תוכל לקרוא ממנו?

קובץ h לא צריך להכיל הרבה - רק הצהרות על פונקציות שאתה רוצה לממש בקובץ c, ואולי הצהרות על כל מיני טיפוסים (typedef ו-struct) שאתה רוצה להשתמש בהם.

בעקרון נהוג להפריד בין המיקום של קובץ ה-h לקובץ ה-c, אבל בינתיים כדאי שתשים אותם ביחד.

הסיבה להפריד ביניהם היא שאם אתה כותב חבילה על מנת שמישהו יוכל להשתמש בה אחר כך בתוכנית שלו, אז אתה צריך לכלול את קובצי ה-h של החבילה הזו בנוסף לקבצים המקומפלים שלה (כדי שמי שמשתמש בחבילה יוכל לדעת איזה פונקציות יש בה).

פורסם
  • מחבר

ותוכל להסביר לי כיצד לבנות קובץ H?

אם אני יוצר קובץ.h מה אני רושם בקובץ עצמו?

איך אני מתחיל?

פורסם
  • מחבר

תודה רבה לך חבר, על כל העזרה.

אני מצטער שהייתי קוץ בישבן, עזרת לי מאוד.

פורסם
  • מחבר

ידידי, שאלה שוב שקשורה לנושא.

יצרתי קובץ H וקובץ C והתכנית עובדת נהדר.

עכשיו אני מעביר את הקבצים לשרתי UNIX, שבהם יש את הקומפיילר gcc (אגב גם בבית אני עובד איתו על הDEV).

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

רק שאני לא יודע בדיוק איך לעשות את זה (מה אני צריך לרשום בcommand של הUnix).

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

תוכל אולי לתאר לי שלב שלב מה אני צריך לרשום בunix כדי שיווצר לי הקובץ הזה כמו שצריך?

פורסם

makefile הוא בסך הכול קובץ טקסט ב-syntax מסויים. התוכנה make קוראת אותו.

ברירת המחדל של make היא לחפש קובץ בשם "Makefile" (שים לב ל-M גדולה!) בספריה הנוכחית ולהשתמש בו.

התחביר של makefiles לדברים פשוטים הוא ממש פשוט (ולדברים מסובכים די מסובך :( ). יש מיליון מדריכים באינטרנט, ויש manual שלם באתר של gnu עם דוגמאות והסברים.

עדיף שתסביר לנו במה אתה מתקשה וננסה לעזור.

פורסם
  • מחבר

אוקיי, יש לי כרגע שני קבצים:

targ41.h שבו יש את ההכרזות על הפונקציות והכרזות על קבועים.

targ41.c שבו יש את הMain ואת מימוש הפונקציות.

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

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

הבנתי שצריך לקמפל את קובץ c. וליצור קובץ o. ממנו ואז לקמפל אותו ולקבל a.out שזה קובץ הריצה של התכנית, עד כאן אני יודע.

אבל עכשיו מה אני צריך לרשום בMakefile?

ואחרי שיצרתי את המייקפייל, איך אני מריץ את הmakefile הזה שיגרור את הרצת התכנית?

יצרתי קובץ Makefile שבו רשום:

a.out: targ41.o

gcc targ41.o

targ41.o: targ41.c targ41.h

gcc -c targ41.c

יש TAB לפני הפקודות של הgcc. וכרגע נמצאים בתיקייה 3 קבצים- הC, הH וMakefile.

ואז אני מריץ את הפקודה make ואז רשום לי:

make: *** No rule to make target 'targ41.h', needed by 'targ41.o'. Stop

מה הוא רוצה ממני?

פורסם

בגדול הבעיה היא שאמרת שיש תלות בשם targ41.h אבל אין מטרה (target) בשם הזה.

יתכן שהבעיה היא שהקובץ לא נמצא שם (שם == איפה שmake מחפש אותו).

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

פורסם
  • מחבר

אז איך אני יכול לפתור את הבעיה?

3 הקבצים נמצאים שם, כולל targ41.h, כדאי להוסיף אותו למייקפייל בתור target שתלוי בעצמו? (targ41.h: targ 41.h)

פורסם

לא. לא.

תבדוק ב-manual של make מה החוק הכללי לגבי קבצי h.

לדעתי זה משהו כמו:


%.h:

פורסם
  • מחבר

הכל בסדר, עובד מצוין.

פשוט טעיתי בשם של הקובץ H והתבלבלתי.

ארכיון

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

דיונים חדשים

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.