2013-08-14 2 views
1
이 코드를 확인할 수있는 것처럼

:다양한 방법

#include<stdio.h> 

int main(){ 
    int a[3][4]; 
    int i; 
    for(i=0;i<12;i++){ 
     a[0][i]=12-i; 
     printf("a[0][%i] = %i\n", i, a[0][i]); 
    } 
    return 0; 
} 

제대로 코드 (12) 1. 그러나이 작품에서 번호를 출력합니다

#include<stdio.h> 

int main(){ 
    int a[3][4]; 
    int i; 
    for(i=0;i<12;i++){ 
     a[i][0]=12-i; 
     printf("a[%i][0] = %i\n", i, a[i][0]); 
    } 
    return 0; 
} 

그것을 12, 11, 10, 1, 2, 1. 문제는 무엇입니까? 나는 당신이 2 개의 루프와 변수를 사용하여 그것을 인쇄 할 수 있다는 것을 알고 있지만, 나는 이렇게하는 법을 배우려고 노력하고있다.

+0

"이 방법을 배우는 방법을 배우려고합니다."- 그냥 확인하지 마십시오. 규칙을 위반하여 코딩하는 방법을 배우는 것은 좋은 생각이 아닙니다. 선형 인 <->을 2 차원 매핑으로 만들려면 때때로 작동하는 '깔끔한 트릭'에 의존하지 마십시오. Heuster의 대답에 따라 맵핑을 적절하게 코딩하십시오. – Skizz

+0

저를 믿으십시오, 나는 당신이 말한 것처럼 코드를 씁니다. 그러나 제 대학교 선생님은 그렇지 않습니다. 그리고 나는이 방법으로 코드를 작성했기 때문에 시험에서 중요한 점을 잃었습니다. – MaranX

+0

어쩌면 이런 종류의 일이 BoundsChecker와 같은 런타임 메모리 검사를 실패하고 다양한 코딩 표준 (예 : MISRA)에 실패 할 것이라는 점을 선생님에게 지적해야 할 것입니다. 그 선생님의 나쁜 습관에 대해 공식적인 불평을 제기 할 수 있는지 궁금합니다. – Skizz

답변

3

두 경우 모두 나쁜 연습을하고 있습니다. 첫 번째 방법이 작동한다는 것은 운이 좋았습니다 (크기가 3 인 하위 배열이 메모리에서 연속적이기 때문에). 우리가, i = 7에 대한 예를 들어

int main(){ 
    int a[3][4]; 
    int i; 
    for(i=0;i<12;i++){ 
     a[i/4][i%4]=12-i; 
     printf("a[%i][%i] = %i\n", i/4, i%4, a[i/4][i%4]); 
    } 
    return 0; 
} 

: /% : 당신이 한 차원 루프에서 2 차원 배열 작업 할 경우

, 당신은 정수 나누기의 두 가지 방법을 사용한다 i/4 == 1 ('나누기 및 정수로 내림') 및 i%4 == 3 ('나누기 후 나머지').

0

데이터가 메모리에 저장되는 방식과 관련이 있습니다. 첫 번째 경우에는 순차적으로 추가하고 3 * 4 = 12 요소에 대한 공간이 있습니다. 운좋게도 모든 요소를 ​​내부에 넣을 수 있습니다. 전체적으로 3 * 4 셀이 있습니다. 두 번째 경우에는 각 행의 첫 번째 셀에만 데이터를 넣으려고하지만 12 행을 표시하지 않고 3 행을 표시했습니다. 다중 차원 배열 메모리에 대한 자세한 내용 는, 이쪽을 봐 :

How are multi-dimensional arrays formatted in memory?

+0

지금은 이해 했으므로 행에는 작동하지만 행에는 작동하지 않습니다. 고맙습니다. – MaranX

+0

모호한 개념적 '<-->'관계를 C 등호로 대체하려면''[rowindex] [columnindex] <--> * (& a [0] [0] + rowindex * columns + columnindex)'라고 쓰고 싶을 수도 있습니다. 'a'만으로는 충분하지 않습니다. 당신은 정말로'int'에 대한 포인터를 갖고 싶습니다 ('(int *) a'도 작동합니다). – anatolyg

+0

이 부분은 내가 쓰는 방식대로는 아니므로, 그것을 묻는 사람과 다른 모든 사람들을 혼동하지 않도록 삭제했습니다. 불편을 끼쳐 드려 죄송합니다. –

-1
+---------------------------------------------------------------------------------+ 
| a[0][0]  <--a[0][1]   <--a[0][0]         | 
| a[0][1]  <--a[0][2]              | 
| a[0][2]  <--a[0][3]              | 
| a[0][3]   .               | 
| a[1][0]   .   <--a[1][0]         | 
| a[1][1]   .               | 
| a[1][2]   .               | 
| a[1][3]   .               | 
| a[2][0]   .   <--a[2][0]         | 
| a[2][1]   .               | 
| a[2][2]  <--a[0][10]              | 
| a[2][3]  <--a[0][11]              | 
|  ^   ^   <--a[3][0] <-- already memory overflow ! | 
|  |    |    .          | 
| array memory  Y 1th code   .          | 
|         others all memory overflow!     | 
|                     | 
|          you 2th code        | 
+---------------------------------------------------------------------------------+ 

그래서, 당신은 그냥 확인 어떤 메모리 오버 플로우를하지 않습니다 a[i/4][i%4]을 사용할 수 있습니다.

말하자면 : 물론 첫 번째 코드는 옳다. 나는 운이 좋다고 생각하지 않는다. C에서 2 차원 배열은 항상 2 차원 입체 구조로되어있다. 그러나, 내 downvote를 참조하십시오, 그것은 그것을 사용하는 것이 좋지 않습니다.

정말 속도가 필요하다면 /을 원하지 않고 '%'라고 생각하면 1 번째 코드를 계속 사용할 수 있다고 생각합니다.

+1

'a [0] [i]'를 사용하면'i'가 두 번째 차원의 경계를 초과 할 때 C 규칙에 위배됩니다. 일부 C 구현에서 가끔 작동한다고해서 항상 작동한다는 것을 의미하지는 않습니다. 사람들에게 사용을 권하지 마십시오. –

+0

@EricPostpischil 1. 우리가'a [2] [2] = {1,2,3,4};를 사용할 수 있다면'왜 [a [0] [i]'를 사용할 수 없습니까? 컴파일러에 익숙하다. * 일부 C 구현에서 때때로 작동한다 * 항상 작동한다는 것을 의미하지는 않는다 * 다른 컴파일러가 다른 방식으로 처리한다는 것을 의미 하는가? –

+0

1. C 언어 표준은 배열 배열과 같은 복합 객체에 값을 제공하는 데 사용되는 이니셜 라이저 목록을 지정합니다. 마지막 차원에서 범위를 벗어난 주소 지정을 사용하여 다차원 배열 요소에 액세스 할 수 있음을 지정하지 않습니다. 이니셜 라이저 목록은 컴파일 타임에 배열 요소와 일치합니다. 그것은 subscripting하는 방식으로 주소를 계산하는 것을 포함하지 않습니다. 2. 예, 다른 컴파일러와 C 구현은 다양한 방법으로 다르게 수행 할 수 있습니다. 배열 경계를 적용 할 수 있으며, 일부는 디버깅 기능으로 구현할 수 있습니다. –

관련 문제