2차원배열을 다른 함수에 전달시...

soulframe의 이미지

main에서

array[n][m] 형식으로 생성한 2차원배열을

서브함수에서 자유자재로 사용하는 방법이 없을까요?

n,m은 길이가 가변적이라서

function(type *array[][m]) 등의 형식을 적용하기가 어렵거든요.

이것때문에 고민인데 누가 답변좀 해주세요...

서브함수에서도 array[n][m]등으로 접근할 수 있으면 좋겠네요

frag의 이미지

soulframe wrote:
function(type *array[][m])

function(type *array)
{
    ...
}

int main()
{
    type array[n][m];

    function(array);
}

이렇게 넘기면 됩니다..

물론 function 내에서도 array[n][m] 이렇게 사용 할 수 있고여.

n,m 의 길이가 가변적이라면

int n, m;

...

type array[n][m];

이런식의 선언은 안될텐데여...머 컴파일러에 따라서 가능한 컴파일러도

있겄지만(??)

크기가 가변적이라면

int n, m;

...

type *array;

array = (type *)malloc(n * m);

이렇게 하시면 됩니다..

사용은 array[n][m] 이렇게 사용할수 있고여...2차원 배열 사용하듯이..

crimsoncream의 이미지

frag wrote:

크기가 가변적이라면

int n, m;

...

type *array;

array = (type *)malloc(n * m);

이렇게 하시면 됩니다..

사용은 array[n][m] 이렇게 사용할수 있고여...2차원 배열 사용하듯이..

이건 안될겁니다.
array의 type이 type *이므로 array[x][y]은 (*(array + x))[y]이 되니까 허용이 안됩니다. 그렇다고 단순히 (&array[x])[y]하게 되면 *(array + x + y) 정도가 되니까 이것도 안되구요.
굳이 이차원 배열로 쓰시겠다면 ((type (*)[m])array)[x][y]으로 casting해서 쓰시거나 (&array[x * m])[y]로 계산을 해서 쓰셔야 할겁니다.
근데 뭐니뭐니해도 *(array + x*m + y) 아닌가요? 정이게 맘에 안드시면 macro하나 만드셔도 되겠지요.

오늘 우리는 동지를 땅에 묻었습니다. 그러나 땅은 이제 우리들의 것입니다.
아직도 우리의 적은 강합니다. 그러나 우리는 그들보다 많습니다.
항상 많을 것입니다.

charsyam의 이미지

soulframe wrote:
main에서

array[n][m] 형식으로 생성한 2차원배열을

서브함수에서 자유자재로 사용하는 방법이 없을까요?

n,m은 길이가 가변적이라서

function(type *array[][m]) 등의 형식을 적용하기가 어렵거든요.

이것때문에 고민인데 누가 답변좀 해주세요...

서브함수에서도 array[n][m]등으로 접근할 수 있으면 좋겠네요

타입도 알고 크기도 알수만 있다면, 저는 그냥 2차원 포인터를 1차원으로
타입 캐스팅 한다음 거기서 다시 2차원으로 타입캐스팅 해서 쓰겠습니다.
고운 하루되시길...

=========================
CharSyam ^^ --- 고운 하루
=========================

mr.lee의 이미지

C++ 을 사용한다면,

이렇게 해보는것도 꽤나 흥미롭지요...

#include <iostream>

class Dummy {
    public:
        int a;
};

template<typename T>
class ArrayType {

    private:
        T* ptr;

    public:
        const size_t length;

        ArrayType(size_t a) : length(a) {
            ptr = new T[a];
        }
        ArrayType(size_t a, size_t b) : length(a) {
            ptr = new T[a](b);
        }
        virtual ~ArrayType() {
            delete[] ptr;
        }
        T& operator[](size_t m) {
            return ptr[m];
        }

};

template<typename T>
struct Array {
    typedef ArrayType<T> D;
    typedef ArrayType<D> DD;
};

void dimensionOnePrimitive(Array<int>::D& a) {
    std::cout << a.length << std::endl;
    std::cout << a[1] << std::endl;
}

void dimensionOneObject(Array<Dummy>::D& a) {
    std::cout << a.length << std::endl;
    std::cout << a[1].a << std::endl;
}

void dimensionTwoPrimitive(Array<int>::DD& a) {
    std::cout << a.length << std::endl;
    std::cout << a[1].length << std::endl;
    std::cout << a[1][2] << std::endl;
}

void dimensionTwoObject(Array<Dummy>::DD& a) {
    std::cout << a.length << std::endl;
    std::cout << a[1].length << std::endl;
    std::cout << a[1][2].a << std::endl;
}

int main() {
    {
        Array<int>::D a(3);
        a[1] = 5;
        dimensionOnePrimitive(a);
    }
    {
        Array<Dummy>::D a(3);
        a[1].a = 5;
        dimensionOneObject(a);
    }
    {
        Array<int>::DD a(3, 4);
        a[1][2] = 5;
        dimensionTwoPrimitive(a);
    }
    {
        Array<Dummy>::DD a(3, 4);
        a[1][2].a = 5;
        dimensionTwoObject(a);
    }

    return 0;
}

결과:

3
5
3
5
3
4
5
3
4
5
익명 사용자의 이미지

        ArrayType(size_t a, size_t b) : length(a) {
              ptr = new T[a](b);
        }

ArrayType<int> 로 쓰게되면 이 부분은
new int[a](b);
와 같은 의미가 되지 않나요? 이렇게 되면 컴파일이 안 될 것 같은데 실제로는 잘 돌아가네요. 어려워요. :?

익명 사용자의 이미지

Anonymous wrote:
        ArrayType(size_t a, size_t b) : length(a) {
              ptr = new T[a](b);
        }

ArrayType<int> 로 쓰게되면 이 부분은
new int[a](b);
와 같은 의미가 되지 않나요? 이렇게 되면 컴파일이 안 될 것 같은데 실제로는 잘 돌아가네요. 어려워요. :?

제 생각에도

ptr = new T[a*b];

처럼 써야 할 것 같은데 에러가 안난다니 신기하네요. 누가 설명좀...

doldori의 이미지

        ArrayType(size_t a, size_t b) : length(a) { 
              ptr = new T[a](b); 
        } 

이것은 gcc의 확장 기능을 이용한 것으로 이식성은 없는 코드입니다.
C++에서 2차원 배열과 같은 기능이 필요하다면 따로 만들 필요는 별로 없지요.
vector<vector<T> >나 boost::multi_array 등을 이용할 수도 있고
행렬 계산을 집중적으로 해야 한다면 valarray를 이용할 수도 있습니다.
mr.lee의 이미지

지금 이 코드는 제가 진행하고 있는 자바->C++ 로 자동 변환기 프로젝트에서 자바배열을 이식하는데 사용되는 개념입니다. (스마트 포인터와 결합되어 이거보다 훨씬 더 복잡하지만...)

이 코드는 이식성이 없지도 않으며 gcc확장도 아닙니다. 코드를 잘 보시면 ArrayType을 직접 사용하는게 아닙니다. Array 를 사용하는거지요... 2차원 배열이 될때 T는 primitive가 아니라 object입니다...

template<typename T> 
struct Array { 
    typedef ArrayType<T> D; 
    typedef ArrayType<D> DD; 
};

이 부분을 잘 봐주시기 바랍니다.

doldori의 이미지

내장형이냐 클래스형이냐는 관계가 없습니다.
ptr = new T[a](b);
이런 문법은 없다는 것을 말한 건데요.
gcc 말고 다른 컴파일러로 시험해 보셨나요?
Comeau가 가장 믿을 만 합니다.

icanfly의 이미지

ArrayType<int> a(3,4) 로 쓰면 문법에러가 나는게 정상아닌가요?

올바른 사용법은 Array<int> a(3,4) 인걸로 보여지고....

SaNha님께서도 그렇게 말씀하신거같은데......

그럼 ArrayType 클래스는 외부적으로 공개하면 안되겠군요.

근데 어떻게 에러가 안나고 잘된다는건지..모르겠네요.

템플릿이 나오면 역시 머리가 좀 아파지는군요.. :lol:

mr.lee의 이미지

comeau 재밌군요 :-)

객체배열의 인스턴스 생성시에 아규먼트 전달이 ANSI C++은 아니었나 보네요. 표준인줄 알았는데..

그래도 gcc에서 되면 거의 모든곳엔(gcc로 웬만한 플젝은 다 되기에) 다 된다고 봐도 되지 않을까요? ;-)

다른 컴팔러를 사용해야 하는곳엔 저 구문을 풀어서 사용해야 할것 같군요. 저 상태가 가장 매력적인 코드라고 봐지긴 하지만...

혹시 gcc 확장에 대해서 좀더 볼려는 참조할만한 링크가 있을련지요?

doldori의 이미지

SaNha wrote:

객체배열의 인스턴스 생성시에 아규먼트 전달이 ANSI C++은 아니었나 보네요. 표준인줄 알았는데..

배열 형태의 new는 디폴트 생성자만을 통해 초기화됩니다.
Array<int>:: D* p = new Array<int>:: D(3);
이런 것은 가능합니다.

SaNha wrote:

그래도 gcc에서 되면 거의 모든곳엔(gcc로 웬만한 플젝은 다 되기에) 다 된다고 봐도 되지 않을까요? ;-)

gcc가 그런 대로 표준을 따르는 편이긴 하지만 이에 전적으로 의존하는 것은
좀 위험합니다. 최소한 2개 이상의 컴파일러로 시험하거나, 표준을 따르는지
진지하게 고려할 상황이라면 표준문서를 참고하는 것이 가장 좋겠지요.

SaNha wrote:

다른 컴팔러를 사용해야 하는곳엔 저 구문을 풀어서 사용해야 할것 같군요. 저 상태가 가장 매력적인 코드라고 봐지긴 하지만...

저 구문을 풀어서 원하는 방식대로 초기화할 수 있는 방법이 있는지는 의문입니다.
아마 구현 방법부터 달리 해야 할 듯 한데요.

SaNha wrote:

혹시 gcc 확장에 대해서 좀더 볼려는 참조할만한 링크가 있을련지요?

저도 이에 대해서는 잘 모릅니다만 역시 gcc 문서를 봐야 하지 않을까요?
ㅡ,.ㅡ;;의 이미지

array[n][m];
으로 생성했다면

님이 원하는 array[a][b]의 접근을

array[a*m + b]
로 쓰셔도 되고

*( array + a*m + b )
로 해도 되고 자유로운데 문제가 있나요?

포인터는 포인터 로쓰고 배열은 배열로 써야죠..

억지로 포인터를 배열식으로 표현하겠다는건 이해가 잘가질않는군요..

기름을 셀때 한드럼두드럼 세는데 소를셀때도 소한드럼두드럼으로 세고 싶다는거나 마찬가지 아닐까요..ㅡ,.ㅡ;;


----------------------------------------------------------------------------

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.