2012-02-10 25 views
5

मैं एक पुराने सी किताब [एएनएसआई सी का एक फर्स्ट बुक] में से कुछ उदाहरण कर रहा हूँ और एक त्रुटि हो रही है इस उदाहरण कोड को संकलित करने का प्रयास करते समय से उदाहरण संकलन:त्रुटियाँ एएनएसआई सी किताब, लिंक्ड सूचियाँ अध्याय

#include <stdio.h> 

struct tele_typ { 
    char name[30]; 
    char phone_no[15]; 
    struct tele_typ *nextaddr; 
}; 

main() { 
    struct tele_typ t1 = {"Acme, Sam", "(201) 555-6678"}; 
    struct tele_typ t2 = {"Dolan, Edith", "(213) 682-3104"}; 
    struct tele_typ t3 = {"Lanfrank, John", "(415) 718-4581"}; 
    tele_typ *first; /* create a pointer to a structure */ 

    first = &t1;   /* store t1's address in first */ 
    t1.nextaddr = &t2; /* store t2's address in t1.nextaddr */ 
    t2.nextaddr = &t3; /* store t3's address in t2.nextaddr */ 
    t3.nextaddr = NULL; /* store the NULL address in t3.nextaddr */ 

    printf("\n%s %s %s",first->name,t1.nextaddr->name,t2.nextaddr->name); 
} 

gcc newstruct.c -o newstruct से उत्पादन ..और:

newstruct.c: In function 'main': 
newstruct.c:13:3: error: unknown type name 'tele_typ' 
newstruct.c:15:9: warning: assignment from incompatible pointer type [enabled by default] 
newstruct.c:20:28: error: request for member 'name' in something not a structure or union 

यह लिंक्ड सूचियों पर अध्याय 10.4 है। क्या किताब में कोई त्रुटि है? या मानकों/gcc version 4.6.2 20120120 (prerelease) में कुछ बदल गया है? धन्यवाद!

+0

क्या आप पुस्तक में कोड देख सकते हैं? क्या यह वास्तव में 'tele_typ * पहले घोषित करता है; ', और पहले' tele_type * struct 'नहीं;'? या आपने इसे टाइप करते समय 'स्ट्रक्चर' कीवर्ड को याद किया था? –

+0

[पुस्तक] का कौन सा संस्करण (http://www.amazon.com/First-Book-Fourth-Iprroduction-Programming/dp/1418835560) क्या आप इसका उपयोग कर रहे हैं? (पेपरबैक के लिए $ 166.95 सूची मूल्य? वास्तव में?) –

+0

यहां कीथ की एक तस्वीर है: http://i.imgur.com/hXnwX.jpg द्वितीय संस्करण, आईएसबीएन: 0-314-01086-6 एक दोस्त मुझे कुछ साल पहले किताब दी। मैं सी सीखने की कोशिश करने से विचलित हो गया (पाइथन पर लगा हुआ ...) और फिर से दिलचस्पी लेना शुरू कर दिया है :) – nak

उत्तर

2

आपके कोड में निम्नलिखित त्रुटियां हैं, उनमें से कुछ मामूली हैं।

  1. main()int main(void) की जरूरत है। main() फ़ॉर्म एक पुरानी शैली की परिभाषा है; इसे 1 9 8 9 एएनएसआई सी मानक के रूप में बहिष्कृत किया गया है, और 1 999 के आईएसओ सी मानक के तहत फ्लैट-आउट अवैध है, जिसने "अंतर्निहित int" नियम को छोड़ दिया। () के बजाय (void) का उपयोग करके यह स्पष्ट हो जाता है कि main कोई पैरामीटर नहीं है; () फॉर्म अभी भी मान्य है, लेकिन 1 9 8 9 से इसे हटा दिया गया है। कई सी कंपाइलर्स पिछड़े संगतता के लिए इस तरह की पुरानी शैली की विशेषताओं को स्वीकार करेंगे, लेकिन कम से कम उनके अनुरूप मोड में चेतावनी देंगे। आपको यह पता लगाना चाहिए कि आपके कंपाइलर के लिए ऐसी चेतावनियां कैसे सक्षम करें।

  2. tele_typ *first;struct tele_typ *first; होना चाहिए। यह मुख्य समस्या है। (typedef जोड़ना इस के आसपास काम करने का एक और तरीका है, लेकिन यह बिल्कुल अनावश्यक है। कोड पहले से ही struct tele_typ के रूप में संदर्भित करता है; आपको बस इतना लगातार करने की आवश्यकता है।) ध्यान दें कि सी ++ में आप इस प्रकार को struct tele_typ या बस tele_typ - बेशक, सी ++ विभिन्न नियमों के साथ एक अलग भाषा है।

  3. आपके पास प्रिंट करने वाली स्ट्रिंग के अंत पर \n होना चाहिए; आपको शुरुआत में इसकी आवश्यकता नहीं है।

    printf("%s %s %s\n",first->name,t1.nextaddr->name,t2.nextaddr->name);

  4. आप अपने main समारोह में समापन } से पहले एक return 0; होना चाहिए। 1 9 8 9 के एएनएसआई सी मानक (या समकक्ष 1 99 0 आईएसओ सी मानक) के रूप में, main के अंत में एक मूल्य लौटाए बिना कॉलिंग पर्यावरण को एक अनिर्धारित परिणाम देता है। 1 999 के मानक के अनुसार, main के अंत से गिरने से एक अंतर्निहित return 0; है, लेकिन इसके बारे में स्पष्ट होने में कोई हानि नहीं है।

चेतावनी सक्षम होने पर, कुछ compilers, की t1, t2, और t3 घोषणाओं पर initializers लापता के बारे में शिकायत कर सकते हैं जब से तुम nextaddr सदस्य के लिए मान प्रदान नहीं किया। यह ठीक है, क्योंकि (ए) जब तक आपके पास प्रारंभकर्ता नहीं है, तब तक कोई भी निर्दिष्ट सदस्य शून्य (प्रारंभकर्ता के मामले में, एक शून्य सूचक के लिए) में प्रारंभ किया जाता है, और (बी) आप बाद में इन सदस्यों को मूल्यों को स्पष्ट रूप से असाइन करते हैं ।

मुझे लगता है कि आप जीसीसी का उपयोग कर रहे हैं। -ansi-std=c99 करने के लिए या -std=c1x आप सी मानक के एक नए संस्करण के खिलाफ परीक्षण करना चाहते हैं, तो

gcc -ansi -pedantic -Wall -Wextra 

बदलें: चेतावनी का एक अच्छा सेट प्राप्त करने के लिए, तो आप इस का उपयोग कर सकते हैं। ध्यान दें कि -ansi या -std=... विकल्पों में से एक का उपयोग कुछ गैर मानक एक्सटेंशन अक्षम कर सकते हैं। कभी-कभी आपको गैर पोर्टेबल कोड लिखने की आवश्यकता होती है; उस स्थिति में, आप उस विकल्प को छोड़ सकते हैं, और शायद -pedantic भी। लेकिन यह प्रोग्राम किसी भी एक्सटेंशन का उपयोग नहीं करता है, और इसकी आवश्यकता नहीं है।

2

आप फ़ंक्शन मुख्य की चौथी पंक्ति की शुरुआत में 'संरचना' खो रहे हैं। इसे

struct tele_typ *first; 

यह सी ++ में ठीक काम करता, क्योंकि 'संरचना' कीवर्ड वैकल्पिक है, लेकिन सी में इसकी आवश्यकता है।

1

आप कुछ इस तरह के लिए सूचक संरचना घोषणा बदलना होगा:

struct tele_typ *first; /* create a pointer to a structure */ 

क्यों, क्योंकि आप पहले से एक सीधा प्रकार के रूप में संरचना tele_type निर्धारित नहीं किया है, तो आप अभी भी यह struct tele_typ का उपयोग करने में बात करने के लिए है ।

typedef struct TELE_TYP { 
    char name[30]; 
    char phone_no[15]; 
    struct TELE_TYP *nextaddr; 
}tele_typ; 

आप पहले से परिभाषित प्रकार के लिए फोन करने में सक्षम हो गया होता और यह ठीक किया गया है अगर आप लिखा था होगा::

आप दूसरे पक्ष पर कुछ इस तरह किया था तो

tele_typ *first; 

लांग छोटी कहानी, पुस्तक गलत है: पी

+0

संरचना नाम के आसपास '__' की आवश्यकता नहीं है; structs टाइप किए गए नामों की तुलना में एक अलग नेमस्पेस में हैं। – sarnold

+1

हालांकि निश्चित रूप से कोई ज़रूरत नहीं है, यह संरचना प्रकार और परिभाषा पहचानकर्ता के बीच अंतर बनाने का सबसे आसान तरीका है। मुझे लगता है कि हर किसी की अपनी शैली है। –

+1

डबल अंडरस्कोर से शुरू होने वाले पहचानकर्ता आरक्षित हैं। आपको * अपने * कोड में कभी भी उनका उपयोग नहीं करना चाहिए। स्ट्रक्चर टैग और टाइपपीफ के लिए अलग-अलग पहचानकर्ताओं का उपयोग करने की आवश्यकता नहीं है; 'typedef struct tele_typ {/ * ... * /} tele_typ;' पूरी तरह से कानूनी है, और आपको इस प्रकार को 'tele_typ' या' struct tele_typ 'के रूप में संदर्भित करने देता है। लेकिन चूंकि पिछले तीन घोषणाएं पहले से ही 'struct tele_typ' प्रकार के रूप में संदर्भित करती हैं, इसलिए इसे 'struct tele_typ' के रूप में संदर्भित करने के लिए बहुत अधिक समझदारी होती है, और * 'typedef' * से परेशान नहीं होती है। –

2

इस लाइन गलत है:

tele_typ *first; /* create a pointer to a structure */ 

आप struct कीवर्ड भूल गए हैं।

इसके अलावा, main को वास्तव में int लौटने के रूप में घोषित किया जाना चाहिए, और return के साथ समाप्त होना चाहिए।

3

मैं पहली चेतावनी को पुन: पेश नहीं कर सका; क्या आप वाकई कोड चिपका चुके हैं वह कोड है जो आपको चेतावनी देता है?

त्रुटि unknown type name 'tele_typ' ठीक करने के लिए आसान है: आप एक प्रकार struct tele_typ घोषित किया है, लेकिन लाइन के सामने struct की जरूरत नहीं है:

struct tele_typ *first; /* create a pointer to a structure */ 
:

tele_typ *first; /* create a pointer to a structure */ 

आप को यह बदलते हैं तो

यह बिना त्रुटि के संकलित करेगा। (और मेरे जीसीसी-4.5.real में चेतावनी के बिना भी (उबंटू/लिनारो 4.5.2-8ubuntu4) 4.5.2।)

यदि आप समारोह शरीर बिल्कुल के रूप में-है, तो आप भी जोड़ सकते हैं, संकलित करने के लिए चाहता था:

typedef struct tele_typ tele_typ; 

तुरंत struct tele_typ परिभाषा के बाद:

struct tele_typ { 
    char name[30]; 
    char phone_no[15]; 
    struct tele_typ *nextaddr; 
}; 

typedef struct tele_typ tele_typ; 

लेकिन मैं मैं एक सी पुस्तक के बारे में थोड़ा चिंतित हूं जो main() को रिटर्न प्रकार या टाइप किए गए पैरामीटर को फ़ंक्शन नहीं देता है। int main(int argc, char* argv[]) या int main(int argc, char** argv) सामान्य है, और इन दो विकल्पों से विचलित कोई भी पुस्तक मुझे थोड़ा अजीब के रूप में मारती है। The C Programming Language एक अच्छी किताब है; इसकी स्पष्टता और शुद्धता के लिए इसे सुधारना मुश्किल है। मूल पर स्विच करने पर विचार करें।

+0

हालांकि मैं आपकी चिंता को समझता हूं, मुझे याद है जब मैंने सी सीखा, तो मेरा शिक्षक हमेशा उन चीजों को जोड़ देगा (इनपुट और आउटपुट प्रकार), बाद में आप जान लेंगे कि वे क्या हैं। और यह केवल मुझे भ्रमित करेगा। मुझे लगता है कि यह या तो क्रमिक हो सकता है या नहीं, मैं उन्हें जोड़ने से पहले एक स्पष्टीकरण पसंद करता। –

+0

हे, हाँ, 'सार्वजनिक स्थैतिक int मुख्य (स्ट्रिंग तर्क []) {...}' मेरे दिमाग में मेरे पहले जावा दिनों से जला दिया गया है, भले ही इस समय कोई फर्क नहीं पड़ता कि समारोह को स्थिर होना क्यों था 'या एक कक्षा में। किसी भी तरह सी 'int मुख्य (int argc, char * argv [])' हमेशा मुझे अधिक समझ में आया। मुझे लगता है कि मैं सरल और सरल भाषाएं अधिक समझ में आता हूं। :) – sarnold

+0

आह, आप सही हैं मैंने कोड को संपादित किया है और पुराने आउटपुट का उपयोग किया है, मैंने पोस्ट कोड से मेल खाने के लिए आउटपुट बदल दिया है। – nak

1

टाइपपीफ का उपयोग करना निश्चित रूप से जाने का तरीका है।

बस एक क्विबल: अग्रणी डबल अंडरस्कोर आरक्षित हैं; उन्हें एप्लिकेशन प्रोग्रामर द्वारा उपयोग नहीं किया जाना चाहिए क्योंकि वे नामस्थान समस्याओं का कारण बन सकते हैं।

कर्नाहन & रिचे पुस्तक "द सी प्रोग्रामिंग भाषा" सर्वश्रेष्ठ पुस्तक बार कोई नहीं है। हालांकि, शुरुआत के लिए यह एक कठिन नारा है। जिस व्यक्ति ने प्रश्न पोस्ट किया है वह किताब स्पष्ट रूप से गलत है!

+1

टाइपिफ़ "निश्चित रूप से जाने का तरीका" क्यों है? कोड पहले से ही पिछले तीन पंक्तियों पर 'struct tele_typ' के रूप में प्रकार को संदर्भित करता है; एक बेहतर समाधान 'संरचना' कीवर्ड को चौथी पंक्ति में जोड़ना है। –