2015-11-05 5 views
5

मैं जावा से सी में एक प्रोग्राम को बदलने की कोशिश कर रहा हूं, यह घड़ी का एक एमुलेटर है और मैं उस समय को प्रदर्शित करने के लिए हूं जब मैं असीसी कला का उपयोग कर रहा हूं। मैं 2 डी चार सरणियों में सभी संख्याओं (0-9) को संग्रहीत किया है (fx 9।):नया से सी, 2 डी सरणी पर वापसी सूचक

char nine[7][5] = { 
    { '0', '0', '0', '0' }, 
    { '0', ' ', ' ', '0' }, 
    { '0', ' ', ' ', '0' }, 
    { '0', '0', '0', '0' }, 
    { ' ', ' ', ' ', '0' }, 
    { ' ', ' ', ' ', '0' }, 
    { ' ', ' ', ' ', '0' } 
}; 

अब मैं एक समारोह काम एक पूर्णांक सरणी (fx में संग्रहीत समय परिवर्तित करने के लिए है जो है 22।: 04:59, सरणी में 22045 9 के रूप में संग्रहीत किया जाएगा)। फ़ंक्शन को प्रत्येक अंक पर संबंधित असीसी कला वापस करनी चाहिए, ताकि मैं आखिरकार उस फ़ंक्शन को कॉल कर सकूं जो समय (एसीआईआई फॉर्म में) प्रिंट करता है जो 6 char [] [] पैरामीटर लेता है।

void printScreen(char hourFirstDigit[7][5], char hourSecondDigit[7][5], char minuteFirstDigit[7][5], char minuteSecondDigit[7][5], char secFirstDigit[7][5], char secSecondDigit[7][5]) 

जावा में मेरे समाधान एक समारोह है कि एक चार [] [] सरणी वापस आ बनाने के लिए बस गया था, और उसके बाद:

तो संक्षेप में, मुझे पता है कि जो 6 मानकों के साथ इस समारोह कॉल करने की आवश्यकता 10 मामलों के लिए एक स्विच बयान (0-9), (यहाँ है पहले कुछ पंक्तियां):

char timeToAsciiArt[][](int digitNumber, int small) { 
switch (timeRightNow[digitNumber]) { 
    case 0: 
    return zero; 
} 

संभव समाधान: मैं पढ़ा है कि वहाँ जहां समस्या के लिए कम से कम दो संभव समाधान (सामान्य रूप में), 1. एक सूचक से एक सरणी में बदलें। 2. एक संरचना के साथ लपेटें।

मेरे विचार पर: 1. मैं सच में यकीन है कि कैसे मैं एक सरणी के लिए सूचक में हो जाएंगे नहीं कर रहा हूँ (किसी कैसे मामले 0 के साथ ऐसा करना समझा सकता है: एक उदाहरण के रूप :)

+2

'char (* timeToAsciiArt (int, int)) [7] [5] {स्विच (/ ** /) {केस 0: वापसी &zero;}}'। वैकल्पिक रूप से: 'char (* timeToAsciiArt (int, int) [5] {स्विच (/ ** /) {केस 0: शून्य लौटें;}}' – EOF

+0

धन्यवाद एक गुच्छा, मैं आपके समाधान का उपयोग कर समाप्त हुआ :)। – Akudo

उत्तर

2

मैं? निम्नलिखित का सुझाव दे रहा हूँ। दृष्टिकोण।

एक फ़ंक्शन को परिभाषित करें जिसमें स्थैतिक संग्रहण अवधि वाली छवियों की एक सरणी होगी।

उदाहरण

char (*)[7][5] get_image(size_t i) 
{ 
    static char images[10][7][5] = 
    { 
     //... 
     { 
      { '0', '0', '0', '0' }, 
      { '0', ' ', ' ', '0' }, 
      { '0', ' ', ' ', '0' }, 
      { '0', '0', '0', '0' }, 
      { ' ', ' ', ' ', '0' }, 
      { ' ', ' ', ' ', '0' }, 
      { ' ', ' ', ' ', '0' } 
     } 
    }; 

    const size_t N = sizeof(images)/sizeof(*images); 

    return i < N ? images[i] : NULL; 
} 

लिए

या हो सकता है यह समारोह लौट प्रकार char (*)[5]

उदाहरण के लिए

char (*)[5] get_image(size_t i) 
{ 
    static char images[10][7][5] = 
    { 
     //... 
     { 
      { '0', '0', '0', '0' }, 
      { '0', ' ', ' ', '0' }, 
      { '0', ' ', ' ', '0' }, 
      { '0', '0', '0', '0' }, 
      { ' ', ' ', ' ', '0' }, 
      { ' ', ' ', ' ', '0' }, 
      { ' ', ' ', ' ', '0' } 
     } 
    }; 

    const size_t N = sizeof(images)/sizeof(*images); 

    return i < N ? images[i][0] : NULL; 
} 

फिर एक समारोह है कि एक संरचना एक में वापस आ जाएगी लिखना है तो बेहतर होगा संबंधित अंकों के साथ 6 तत्वों की सरणी। ये तत्व कॉल get_image पर कॉल करने के लिए तर्क के रूप में कार्य करेंगे।

यह पर्याप्त है।

1

सी में एक सरणी एक सूचक है। जब आप पैरामीटर पास करते हैं तो यह हमेशा कॉपी द्वारा होता है, इसलिए जब आप एक सरणी भेजते हैं तो आप एक पॉइंटर की एक प्रति भेजते हैं, सरणी की प्रति नहीं।

Structs मूल्य से कॉपी कर रहे हैं (int, float ... के रूप में), और एक स्थिर सरणी के अंदर हो सकता है:

typedef struct { 
    char tab[7][5]; 
}Digit; 

तो तुम वैरिएबल बना सकते हैं: Digit zero, one, two… और मान सेट में: zero.tab[0][0] = ' ';। और आप इसे कार्यों में भेज सकते हैं या इसे वापस कर सकते हैं, इसकी प्रतिलिपि बनाई जाएगी।

अब पॉइंटर्स से निपटने के लिए (मेरी राय में बेहतर है क्योंकि को इन arrays को डुप्लिकेट करने के लिए की आवश्यकता है): एक सरणी अभी भी एक सूचक है।लेकिन "स्थैतिक" 2 डी सरणी थोड़ा अजीब (यह सरणी की सरणी नहीं है) हैं। जैसा कि ईओएफ द्वारा टिप्पणी में उल्लेख किया गया है, आपके सरणी वास्तव में हैं (*) [5]। तो यह कुछ करने के लिए नेतृत्व एक छोटा सा सभी प्रकार के मैच के लिए जटिल:

char (*select_digit(int val))[5] { 
    if (value == 0) return zero; 
    if (value == 1) return one; 
    … 
} 

आपका printScreen समारोह में ही है। एक सूचक इस select_digit समारोह से वापस लौटे तो आप इसे इस घोषित करने के लिए है की दुकान करने के लिए:

char (*tmp)[5]; 
tmp = select_digit(5); 
printScreen(tmp, …); 
+3

एक सरणी एक सूचक नहीं है। यह एक सरणी है। – vdaras

2

मैं समझता हूँ के रूप में, आप करना चाहते हैं:

  • अपने ASCII आर्ट के लिए भंडारण के कुछ प्रकार;
  • एक फ़ंक्शन जो अंक प्राप्त करता है और संबंधित ASCII कला संग्रहण में कुछ सूचक लौटाता है;
  • एक ऐसा कार्य जो एएससीआईआई कला का एक सेट प्राप्त करता है और उन्हें प्रिंट करता है।

ASCII आर्ट भंडारण

यह एक संरचना में अपने ASCII आर्ट रैप करने के लिए बुद्धिमान हो सकता है, क्योंकि आप तो इसके बारे में अधिक डाटा स्टोर कर सकते हैं। शायद भविष्य में आप एक पतला 1 अंक प्राप्त करना चाहते हैं; आप प्रत्येक ASCII आर्ट के आकार के बारे डाटा स्टोर करने की आवश्यकता होगी:

struct ascii_digit { 
    unsigned int width; 
    unsigned int height; 
    char[MAX_HEIGHT][MAX_WIDTH] art; //Here you could instead use a pointer 
            //instead of storing directly 
} 
पाठ्यक्रम यदि आप पूरी तरह से एक निश्चित आकार के अलावा कुछ होने पर योजना नहीं है के

, सरणियों ठीक कर रहे हैं।


सही ASCII आर्ट

ढूँढना जब सी में चारों ओर सरणियों गुजर, आप आमतौर पर सीधे सरणी पारित नहीं है: आप आम तौर पर यह करने के लिए एक सूचक का उपयोग करें। तो अपने समारोह के लिए एक सही प्रोटोटाइप

char time_to_ascii_art[][](int digit_number, int small); 

बल्कि नहीं होगा, अगर आप संरचनाओं

struct ascii_digit* time_to_ascii_art(int digit_number, int small); 

नोट है कि हम एक संरचना करने के लिए एक सूचक वापसी का उपयोग करें। हालांकि संरचना को सीधे पास करना पूरी तरह से संभव है, लेकिन इसे अच्छी प्रथा नहीं माना जा सकता क्योंकि यह आपकी संरचना के आकार के आधार पर कुछ ओवरहेड को प्रेरित करता है।

या आप char की ओर इशारा का उपयोग कर एक सीधी सादी दृष्टिकोण का उपयोग कर सकते हैं:

char* time_to_ascii_art(int digit_number, int small); 

ध्यान दें कि यदि आप एक bidimensional सरणी के लिए एक char* सूचक है, तो आप जब करने की कोशिश कर खुद से गणित करना होगा इसकी सामग्री तक पहुंचें। उदाहरण के लिए, yx वें पंक्ति: array[width * x + y] के वें सदस्य तक पहुंच।ऐसा करने से अपने आप को बचाने के लिए, आप सरणियों की ओर इशारा उपयोग कर सकते हैं:

char (*time_to_ascii_art)(int digit_number, int small)[ASCII_ART_WIDTH]; 

इस समारोह में आप या तो एक switch … case बयान इस्तेमाल कर सकते हैं जैसे आप जावा में किया था (संरचनाओं का उपयोग कर उदाहरण):

// Let's say that your structures are declared in the global scope as ascii_zero, ascii_one… 
struct ascii_digit* time_to_ascii_art(int digit_number, int small) 
{ 
    switch(digit_number) { 
     case 0: 
      return ascii_zero; 
     case 1: 
      return ascii_one; 
     default: 
      return NULL; 
    } 
} 

या आप कर सकते हैं - जो शायद जावा में भी एक अच्छा विचार होगा- आपके एएससीआईआई कला, या उनके लिए पॉइंटर युक्त एक सरणी है, जो n वें सदस्य तक पहुंचने से आपको n:

अंक के लिए ASCII कला प्रदान करेगा।
// Let's now say you have an ascii_digits array of structs containing your digits 
struct ascii_digit* time_to_ascii_art(int digit_number, int small) 
{ 
    return ascii_digits + digit_number; // You should handle bad values. 
    // ascii_digits being an array, it is implicitly cast to a pointer here. 
} 

प्रदर्शन समारोह

अब करने के लिए ASCII कला पासिंग अपने प्रदर्शन समारोह आप कर सकते हैं करने के लिए अपने ASCII कला पारित करने के लिए - डेटाप्रकार आपके द्वारा चुने गए पर निर्भर करता है - संरचनाओं को या तो संकेत का उपयोग करें:

void print_screen(struct ascii_digit* hour_first_digit, …); 

char की ओर इशारा:

void print_screen(char* hour_first_digit, …); 

या वर्ण की सरणी की ओर इशारा:

void print_screen(char (*hour_first_digit)[ASCII_ART_WIDTH], …); 
1

सरणियों और संकेत का उपयोग कर कम या ज्यादा अनुवाद करने के लिए होगा की आपका विचार:

char (* timeToAsciiArt(unsigned timeNow[6], unsigned digitNumber))[5] { 
    static char asc0[7][5] = { //fill in }; 
    static char asc1[7][5] = { //fill in }; 
    switch (timeNow[digitNumber]) { 
    case 0: 
     return asc0; 
    case 1: 
     return asc1; 
    ... 
} 

फिर आप print_screen को लौट कला

unsigned timeNow[] = {1, 2, 3, 4, 5, 6}; 
char (*first_digit)[5] = timeToAsciiArt(timeNow, 0); 
printScreen(first_digit, ... ,); 
द्वारा पारित कर सकते हैं

या सीधे

printScreen(timeToAsciiArt(timeNow, 0) , ...); 

अंत में, यह कहता है कि struct में रैपिंग आपको एक और अधिक पठनीय कोड प्राप्त करेगी।

संबंधित मुद्दे