2차원 배열에서 행과 열은 어느것?

gurumong의 이미지

안녕하세요 ^^
프로그래밍 공부를 하다가 궁금한것이 생겼습니다

int array[2][4]; // 행 2, 열 4
/*
ㅁㅁㅁㅁ
ㅁㅁㅁㅁ
*/

라는 코드가 있으면 ((arrary[2])[4]) 코드와 같지 않습니까?
이것은 2개의 원소를 가지는 배열이 다시 4개가 있다는 것으로 이해할수있을꺼 같은데
어째서 array[열][행]이 처럼 반대로 이해하고 사용하는것일까요?

/*
ㅁㅁ
ㅁㅁ
ㅁㅁ
ㅁㅁ
*/

처럼 이해하고 사용되어야 바른것 같은데...

엉뚱한 질문이지만 정말로 이해가 안가서 질문한거예요 ㅜ.ㅜ

익명사용자의 이미지

단순하게 생각하세요.
0 ~ 29 까지 숫자를 쓴다면

00 01 02 03 04 05 06 07 08 09 
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29

이렇게 쓰겠지요. (우리는 컴쟁이들이므로 항상 0부터 셉니다.)

배열 인덱스의 경우 열을 앞에 쓰면

[0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [0][6] [0][7] [0][8] [0][9] 
[1][0] [1][1] [1][2] [1][3] [1][4] [1][5] [1][6] [1][7] [1][8] [1][9]
[2][0] [2][1] [2][2] [2][3] [2][4] [2][5] [2][6] [2][7] [2][8] [2][9]

이렇게 되어 위의 경우와 같은 순서가 됩니다.
즉 기존의 방식과 비슷하게 해 놓아서 이해하기 쉽도록 해 놓은 것입니다.
익명사용자의 이미지

1차원 배열을 2차원으로 확장할 때 선언 방법을 보시면 차원이 증가할 때마다 배열의 선언 뒤쪽에 붙이는 것이 아니라 앞으로 붙이는 형식으로 되어 있습니다. (메모리에 저장되는 구조를 볼 때)

char a[4]; // 4바이트 1차원 배열
char b[2][4]; // 위의 1차원 배열을 2개 붙여 2차원 배열 생성
char c[3][2][4]; // 위의 2차원 배열을 3개 붙여 3차원 배열 생성

즉, b[2][4]는 메모리에 저장되는 구조가 아래와 같이 나타납니다.

b[0][0] b[0][1] b[0][2] b[0][3] b[1][0] b[1][1] b[1][2] b[1][3]

1차원 배열로 변환했을 때 쉽게 알아볼 수 있으려면 위의 구조를 이해하고 있는 편이 나중에 배열 계산을 할 때 실수를 막는 방법이 될 겁니다.

이 구조가 맞는지 틀리는지 확인해 보려면 간단한 테스트 코드로 검증해 보시면 됩니다.

#include <stdio.h>
 
int main(void)
{
        int i, j, t;
        int array[2][4], *parray;
 
        for( i = 0, t = 0; i < 2; i++ )
        {
                for( j = 0; j < 4; j++ )
                {
                        array[i][j] = t++;
                }
        }
 
        parray = &array[0][0];
 
        for( i = 0; i < 8; i++ )
                printf("array[%d] = %d\n", i, parray[i]);
 
        return 0;
}

만약 메모리 상에서 i와 j 중에 i가 먼저 증가한다고 생각하시면 for 문의 위치를 바꿔 보시기 바랍니다.

ㅡ,.ㅡ;;의 이미지


사용하기 나름이겠지만...

4개짜리 구룹이 2개 있다는걸로 생각해서 맞다고보는데..


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

winner의 이미지

행렬로 생각하시면 됩니다.

gurumong의 이미지

실제로 위의 익명사용자님께서 올려주신 코드를 돌려보니 메모리에 배열이 그런식으로 배치된게 맞군요!
하지만 배열이 ((array[N])[M]) 으로 묶이는데도 불구하고 그런식으로 해놨는지 이해가 안가네요
저 같은 초보자 헷갈리게 말이예요 --;

답변 주신 모든분들 감사합니다 (__)

익명사용자의 이미지

재밌게도 포트란77은 c와 다르다죠.

dimension a(4,3)이라고 변수가 선언되었다면

a(1,1) a(2,1) a(3,1) a(4,1) a(1,2) a(2,2) ... 순서로 저장됩니다.

포트란9x에서는 row major인지 column major인지 지정할 수 있다는군요.

태훈의 이미지

C에서 선언이 해석되는 순서로 메모리 할당된다고 생각하면 안되겠네요.

그러면 C언어에서 메모리 할당 로직은 어떻게 되는거죠?

Just do it!

bus710의 이미지

x[10][5]

하면 10으로 선언한 왼쪽이 y 축입니다...
전 이렇게 외우는게 편하더라구요;;

life is only one time

전웅의 이미지

> 안녕하세요 ^^
> 프로그래밍 공부를 하다가 궁금한것이 생겼습니다
>
> int array[2][4]; // 행 2, 열 4
> /*
> ㅁㅁㅁㅁ
> ㅁㅁㅁㅁ
> */
>
> 라는 코드가 있으면 ((arrary[2])[4]) 코드와 같지 않습니까?
> 이것은 2개의 원소를 가지는 배열이 다시 4개가 있다는 것으로 이해할수있을꺼 같은데
> 어째서 array[열][행]이 처럼 반대로 이해하고 사용하는것일까요?
>

device 님의 질문을 보면 대체로 오해가 무엇인가 내용을 "부족"하게 파악
하신 데서 나오는 것 같습니다.

이번 경우에도 ((array[2])[4]) 로 parsing 한 것까지는 맞지만, 이 의미를
"2개의 원소를 가지는 배열이 다시 4개가 있다는 것"으로 파악하신 것은
잘못된 것입니다. (마치 책을 읽다마신 듯한 느낌이... :-)

C 언어에서 선언에 따른 type 은 명칭에서 가장 "먼" 것부터 유도됩니다.
따라서,

int ((array[2])[4]);

에서 [4] 가 가장 멀리 있으므로,

... array of 4 int

가 됩니다. 그 다음으로 멀리 있는 것이 [2] 이므로

array of 2 array of 4 int
(4개의 원소를 가지는 배열이 다시 2개가 있다는 것)

가 되는 것입니다.

이와 같은 논리를 적용하면,

int (*func)(void);

에서 (void) 가 더 멀리 있으므로,

pointer to function with no parameter returning int
(정수형 반환하고 매개변수 갖지 않는 함수를 가리키는 포인터
- 즉, 함수 포인터)

가 된다는 것을 알 수 있습니다.

>
> /*
> ㅁㅁ
> ㅁㅁ
> ㅁㅁ
> ㅁㅁ
> */
> 처럼 이해하고 사용되어야 바른것 같은데...
>
> 엉뚱한 질문이지만 정말로 이해가 안가서 질문한거예요 ㅜ.ㅜ
>

가장 근본적인 오해가 풀렸으니 행과 열에 대한 오해도 풀렸으리라
생각합니다.

C 언어는 다차원 배열을 "배열의 배열"로 다루는데 비해, 포트란은 다차원
배열 그 자체로 다루기 때문에 포트란의 행과 열 선택과 C 언어의 행과 열
선택에는 다소 근원적인 차이가 있다고 볼 수 있습니다.

위에서 말씀드린 선언 해석에 대한 원칙과 배열 요소는 인접한 곳에
위치한다는 원칙을 합하면 위에 다른 분이 보여주신 코드도 당연한 것으로
이해되실 겁니다.

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

lunayyko의 이미지

안녕하세요,

C언어를 공부하고 있는 비전공자입니다.

"C 언어에서 선언에 따른 type 은 명칭에서 가장 "먼" 것부터 유도됩니다."
-> 중요한 개념이지만 책에 나와있지 않아서 몰랐던 정보입니다!
감사합니다.

gurumong의 이미지

그건...;;;
제가 스스로 이해하려고 노력하다보니 반대로 이해하는쪽이 편하다고 생각되어 그렇게 이해해버린게 문제가 된거 같네요
포인터 부분은 세번이나 꼼꼼히 읽어보고 완전히 다 이해했다고 생각했었는데; 이런 T.T
int *arr(); /* array <- point <- int */
사실 유도되는 과정이 왜 int 부터라고 할까 의문스러웠거든요; 왜 반대로 유도된다고 하지! 하면서요
방금 설명을 듣고 왜 그런지 이해했습니다;;

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.