2010-02-22 16 views
6

पर पॉइंटर पास करना मुझे काफी समय से यह समस्या आ रही है - मैंने वर्ग सदस्य के रूप में आकार 2 डी सरणी तय की है।2 डी सरणी C++

class myClass 
{ 
public: 
     void getpointeM(...??????...); 
     double * retpointM(); 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); ??? 
    A = moo.retpointM(); ??? 

} 

मैं बाहर M मैट्रिक्स के लिए सूचक पारित करने के लिए करना चाहते हैं। यह शायद बहुत आसान है, लेकिन मुझे & और * आदि का उचित संयोजन नहीं मिला है

सहायता के लिए धन्यवाद। , हालांकि

public: 
    double * getMatrix() { return &M[0][0]; } 

वर्ग बाहर, आप वास्तव में नहीं तुच्छता से एक और 2 डी सरणी में double * बदल सकते हैं सीधे, पर:

उत्तर

9

double *A[3][3];double * एस की 2-आयामी सरणी है। आप double (*A)[3][3]; चाहते हैं।

फिर, ध्यान दें कि A और *A और सभी के पास एक ही पता है, बस अलग-अलग प्रकार हैं।

एक typedef चीजों को आसान बनाने में कर सकते हैं बनाना:

typedef double d3x3[3][3]; 

यह किया जा रहा है सी ++, आप संदर्भ द्वारा चर पास करना चाहिए सूचक नहीं:

void getpointeM(d3x3 &matrix); 

अब आप में कोष्ठक का उपयोग करने की जरूरत नहीं है नाम टाइप करें, और संकलक सुनिश्चित करता है कि आप सही आकार की सरणी पारित कर रहे हैं।

+0

आपको संदर्भों का उपयोग नहीं करना चाहिए "क्योंकि यह सी ++ है" या "सिर्फ इसलिए कि आप कर सकते हैं"। जब वे उपलब्ध विकल्पों की तुलना में अधिक स्पष्ट होते हैं तो उनका उपयोग करें। –

+0

@Roger: हाँ, ठीक है, यह यहां उचित है, वैसे भी: v) – Potatoswatter

0

संक्षिप्त उत्तर है कि आप सरणी के शुरू करने के लिए एक double * प्राप्त कर सकते है कम से कम एक पैटर्न में जो मैंने देखा है।

आप मुख्य में 2 डी सरणी बना सकते हैं, हालांकि (डबल ए [3] [3]) और को GetPoint विधि में पास करें, जो मानों को पास-इन सरणी में कॉपी कर सकता है। इससे आपको एक प्रतिलिपि मिल जाएगी, जो आप चाहते हैं (मूल, संशोधित, डेटा के बजाय)। नकारात्मकता यह है कि आपको इसे निश्चित रूप से कॉपी करना होगा।

+0

नहीं! हिम्मत मत हारो! – Potatoswatter

0

अपने main() समारोह में:

double *A[3][3]; 

(युगल करने के लिए या संकेत) double* की एक 3x3 सरणी पैदा करता है। दूसरे शब्दों में, 9 मेमोरी पॉइंटर्स को स्टोर करने के लिए मेमोरी के 9 x 32-बिट संगत शब्द।

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

double *A; 

लेकिन अगर आप एक समारोह है और आप को यह सूचक गुजर रहे हैं:

आप केवल एक आंतरिक वर्ग के सदस्य के लिए एक सूचक वापस करना चाहते हैं, तो आप केवल वास्तव में main() में एक भी सूचक मूल्य की जरूरत है अपने मूल्य अद्यतन करने के लिए समारोह की जरूरत है, आप एक डबल सूचक (जो समारोह फोन करने वाले के लिए वापस असली सूचक मान देने के लिए अनुमति देगा की जरूरत है:

double **A; 

औरअंदर 0 आप बस आंतरिक सदस्य (M) के लिए एक इंगित कर सकते हैं:

getpointeM(double** A) 
{ 
    // Updated types to make the assignment compatible 
    // This code will make the return argument (A) point to the 
    // memory location (&) of the start of the 2-dimensional array 
    // (M[0][0]). 
    *A = &(M[0][0]); 
} 
+0

ठीक है ऐसा लगता है कि मैं वास्तव में ऐसा करना चाहता था :) लेकिन फिर भी त्रुटि के साथ: 'डबल [3] [3]' को परिवर्तित नहीं कर सकता असाइनमेंट में 'डबल *' – Moomin

+0

मेरी गलती क्षमा करें - दोनों पंक्तियों में ** जोड़ने के लिए भूल गए – Moomin

+2

यह सिर्फ मुझे कोई समझ नहीं आता है। सदस्य को 'डबल एम [3] [3] 'घोषित किया गया है। अभिसरण '* ए = एम' बस संकलित नहीं होगा, क्योंकि बाएं हाथ की ओर 'डबल *' है और दाएं हाथ की ओर 'डबल (*) [3]' है। ये प्रकार संगत नहीं हैं। – AnT

0
class myClass 
{ 
public: 
     void getpointeM(double *A[3][3]) 
     { 
      //Initialize array here 
     } 

private: 

    double M[3][3]; 

}; 

int main() 
{ 
    myClass moo; 
    double *A[3][3]; 

    moo.getpointM(A); 
} 
3

आपका आशय स्पष्ट नहीं है। getpointeM क्या करना है? आंतरिक मैट्रिक्स (पैरामीटर के माध्यम से) पर एक सूचक लौटें, या मैट्रिक्स की एक प्रति वापस करें?

एक सूचक लौटने के लिए, आप के रूप में

... 
double (*retpointM())[3][3] { return &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    A = moo.retpointM(); 
} 

इस बल्कि हालांकि पढ़ने के लिए मुश्किल है इस प्रकार इस

// Pointer-based version 
... 
void getpointeM(double (**p)[3][3]) { *p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(double (*&p)[3][3]) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

retpointM के लिए घोषणा लगेगा कर सकते हैं। आप इसे अगर आप अपने सरणी प्रकार

typedef double M3x3[3][3]; 

उस मामले में के लिए एक typedef-नाम का उपयोग उपरोक्त उदाहरण

// Pointer-based version 
... 
void getpointeM(M3x3 **p) { *p = &M; } 
... 
int main() { 
    M3x3 *A; 
    moo.getpointM(&A); 
} 

// Reference-based version 
... 
void getpointeM(M3x3 *&p) { p = &M; } 
... 
int main() { 
    double (*A)[3][3]; 
    moo.getpointM(A); 
} 

// retpointM 
... 
M3x3 *retpointM() { return &M; } 
... 
int main() { 
    M3x3 *A; 
    A = moo.retpointM(); 
} 
0

में बदलना होगा आप में कोड लेने के लिए चाहते हो सकता है एक बहुत साफ देख सकते हैं आपका मुख्य कार्य जो युगल के 2 डी सरणी के साथ काम करता है, और इसे सदस्य कार्य के रूप में myClass में ले जाता है। न केवल आपको उस 2 डी सरणी के लिए पॉइंटर पास करने में कठिनाई का सामना करना पड़ेगा, लेकिन आपकी कक्षा के बाहरी कोड को अब यह जानने की आवश्यकता नहीं होगी कि आपकी कक्षा ए कैसे लागू करती है, क्योंकि अब वे एक फ़ंक्शन कॉल करेंगे myClass और काम करने दे रहा है। यदि, कहें, तो आपने बाद में ए के परिवर्तनीय आयामों को अनुमति देने का निर्णय लिया और vector के vector के साथ सरणी को प्रतिस्थापित करने का विकल्प चुना, आपको इसे काम करने के लिए किसी भी कॉलिंग कोड को फिर से लिखना होगा।

0

निजी के बजाय एम सार्वजनिक बनाएं। चूंकि आप एक सूचक के माध्यम से एम तक पहुंच की अनुमति देना चाहते हैं, एम किसी भी तरह से encapsulated नहीं है।

struct myClass { 
    myClass() { 
    std::fill_n(&M[0][0], sizeof M/sizeof M[0][0], 0.0); 
    } 
    double M[3][3]; 
}; 

int main() { 
    myClass moo; 
    double (*A)[3] = moo.M; 
    double (&R)[3][3] = moo.M; 

    for (int r = 0; r != 3; ++r) { 
    for (int c = 0; c != 3; ++c) { 
     cout << A[r][c] << R[r][c] << ' '; 
     // notice A[r][c] and R[r][c] are the exact same object 
     // I'm using both to show you can use A and R identically 
    } 
    } 

    return 0; 
} 

मैं सामान्य रूप में, पसंद करेंगे आरएक से अधिक क्योंकि लंबाई निर्धारित किया जाता है (एक संभवतः एक double[10][3] को इंगित करता है, तो हो सकता है कि एक आवश्यकता थी) और संदर्भ आमतौर पर होगा के सभी स्पष्ट कोड का नेतृत्व करें।