שגיאת קומפילציה בשפת C: conflicting types for 'my_cos' - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שגיאת קומפילציה בשפת C: conflicting types for 'my_cos'


asiania

Recommended Posts

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

#include <stdio.h>

#include <math.h>

#define PI 3.14159265358979323846

double factorial(int number);

int main()

{

double x,cosinus1,cosinus2;

printf("\nplease enter a value to calculate:\n");

scanf("%lf",&x);

cosinus2=cos(PI-fmod(x,2*PI));

cosinus1=my_cos(x);

printf("\ncosinus as calculated by program is - %lf\ncosinus as calculated by computer is - %lf\n",cosinus1,cosinus2);

}

double factorial(int number)

{

double num;

num=number;

return num==0.0?1.0:(num*factorial(num-1));

}

double my_cos(double x)

{

int i=1;

double cosinus=0.000002;

x=PI-fmod(x,2*PI);

while(fabs(cosinus)>0.000001){

cosinus+=((pow(-1,i)*pow(x,(2*i)))/factorial(2*i));

}

return cosinus;

}

אודה מאוד לעזרתכם. :)

קישור לתוכן
שתף באתרים אחרים

הבעיה היא שאת משתמשת בפונקציה my_cos לפני שאת מצהירה עליה.

כמו שאת מצהירה על הפונקציה factorial לפני ה-main, את צריכה להצהיר גם על my_cos.

הסיבה שהקומפיילר נותן את השגיאה המוזרה הזו היא שהקומפיילר מקמפל את הקובץ לפי הסדר. כשהוא נתקל בפונקציה שהוא לא מכיר (במקרה הזו my_cos) הוא "מנחש" שהפונקציה מחזירה int. כשהוא מגיע לקטע של הקובץ שבו מוגדרת הפונקציה, הוא חושב שאת מנסה להגדיר את הפונקציה מחדש בתור פונקציה שמחזירה double, ואז מתלונן על זה שטיפוס ההחזרה של הפונקציה סותר את מה שהוא ניחש מקודם.

קישור לתוכן
שתף באתרים אחרים

הנה הקוד עם כמה שינויים:


#include <stdio.h>
#include <math.h>
#define PI 3.14159265358979323846

double factorial(int num)
{
return num==0 ? 1.0 : (num*factorial(num-1));
}

double my_cos(double x)
{
double cosinus = 0;
for (int i = 0; i < 100; i++) {
cosinus += ((pow(-1.0,i)*pow(x,(2*i)))/(factorial(2*i)));
}
return cosinus;
}
int main()
{
double x;
printf("please enter a value to calculate:\n");
scanf("%lf", &x);
x = PI-fmod(x,2*PI);
printf("cosinus as calculated by program is: %lf\ncosinus as calculated by computer is: %lf\n", cos(x), my_cos(x));
}

קישור לתוכן
שתף באתרים אחרים

לא חייבים להזיז את my_cos ואת factorial לפני ה-main, מספיק שתהיה שורת הצהרה עליהם לפני ה-main. זה אפילו יותר יפה לדעתי (ככה יש רשימת פונקציות מסודרת בתחילת הקובץ, והתוכנית הראשית נמצאת גם בתחילת הקובץ).

נ.ב. לפותחת הת'רד: כשאת כותבת קוד, אל תצמידי אותו לשמאל, אלא השתמשי בטג קוד.

קישור לתוכן
שתף באתרים אחרים

תודה רבה לשניכם!!

למרות שעכשו יש בעיה חדשה

לגבי כל הפונקציות המתמטיות קופצת שגיאה, למשל : 'undefined reference to 'fmod

(כנ"ל לגבי 'pow' & 'cos')

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

קישור לתוכן
שתף באתרים אחרים

הסבר קטן:

הקומפיילר למעשה עובד בשני שלבים.

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

בשלב השני (שנקרא linkage - קישור) הקומפיילר לוקח את קובץ ה-o שנוצר והופך אותו לקובץ executable. אבל מה, בשביל זה הוא צריך גם את המימוש של הפונקציות שאת משתמשת בהן, שנמצא בקבצים אחרים. התהליך הזה בעצם מקשר בין הפונקציות שיושבות בקבצים השונים.

רוב הפונקציות של הספריה הסטנדרטית של c יושבות בקובץ בשם libc.o, שהקומפיילר תמיד מקשר אותו אוטומטית (ככה שלא צריך לציין אותו במיוחד), אבל הפונקציות המתמטיות יושבות בקובץ בשם libm.o, ש-gcc לא מקשר אוטומטית. אז צריך לומר לו לקשר את הקובץ הזה, וזה מה שהארגומנט lm- עושה: כשמעבירים "lxyz-" לקומפיילר, זה אומר לו "קשר את הקובץ libxyz.o" לתוכנית שלי (l זה קיצור ל-link).

קישור לתוכן
שתף באתרים אחרים

;D

אני שמחה על המידע המפורט

שניצל-אני ממש ממש חדשה כאן, אבל

אני מעריכה מאוד מאוד את רמת התמיכה שלך בפעילי הפורום (כולל אותי)

וכרגיל המון תודה - עזרת לי מאוד. (לא שיצא תרגיל מושלם - אבל הדברים ששאלתי כאן תקעו אותי ימים ונפתרו בשעות בודדות!!!!)

תודה

קישור לתוכן
שתף באתרים אחרים

הסבר קטן:

הקומפיילר למעשה עובד בשני שלבים.

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

בשלב השני (שנקרא linkage - קישור) הקומפיילר לוקח את קובץ ה-o שנוצר והופך אותו לקובץ executable. אבל מה, בשביל זה הוא צריך גם את המימוש של הפונקציות שאת משתמשת בהן, שנמצא בקבצים אחרים. התהליך הזה בעצם מקשר בין הפונקציות שיושבות בקבצים השונים.

רוב הפונקציות של הספריה הסטנדרטית של c יושבות בקובץ בשם libc.o, שהקומפיילר תמיד מקשר אותו אוטומטית (ככה שלא צריך לציין אותו במיוחד), אבל הפונקציות המתמטיות יושבות בקובץ בשם libm.o, ש-gcc לא מקשר אוטומטית. אז צריך לומר לו לקשר את הקובץ הזה, וזה מה שהארגומנט lm- עושה: כשמעבירים "lxyz-" לקומפיילר, זה אומר לו "קשר את הקובץ libxyz.o" לתוכנית שלי (l זה קיצור ל-link).

[list type=decimal]

[*]האם בשלב ה linkage , הפונקציות המיובאות מועתקות לתוך הexe כשפת מכונה, או שהקובץ מתקשר איתם ברגע שהוא מורץ?

[*]האם הפונקציות המתמטיות שהיא השתמשה בקוד הנ"ל אינם חלק מ math.h ? ואם כן מה ההבדל בין הספריה עם סיומת h לבין הספריה עם סיומת o.

תודה רבה.

קישור לתוכן
שתף באתרים אחרים

1. חלק ככה וחלק ככה. זה ההבדל בין לינק סטטי לדינמי. קרא עוד כאן על dynamic linking.

2. שוב, math.h רק מכיל את החתימות של הפונקציות (שם הפונקציה, טיפוסי הפרמטרים וטיפוס ערך ההחזרה), ולא את הקוד של הפונקציות. הקוד עצמו (ליתר דיוק, התרגום שלו בשפת מכונה) נמצא בקובץ o.

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...