• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

(10.13)강의에서 20:34, 21:25, 22:03 부분 질문

22.08.16 22:43 작성 조회수 120

0

강의 20:34에서 char aname [][15]과 같이 2차원 배열을 만들어 문자열 원소들을 초기화 해주었는데 이것이 어떻게 배열안에 저장되는지 이해가 되지 않습니다. 첫번째 배열 인덱스가 지정되지 않았는데 어떻게 초기화 되는 것인가요? 그냥 한 행에 다 들어가는것인가요?

그리고 강의 21:25부분에서 배열의 배열이기 때문에 an = sizeof(aname) / sizeof(char[15])에서 사이즈를  sizeof(char[15])로 나누어 크기를 구했다고 하는데 잘 이해가 되지 않습니다. 하나의 원소의 크기로 나누어 사이즈를 구해야 되는 것이 아닌가요? 제가 생각하기에는 어차피 한 행에 원소들이 다 들어가니까 전체크기를 열의 크기로 나누면 한 행의 사이즈 크기가 나오므로 그 크기만큼 원소를 for문으로 출력해준다고 생각이 되는데 어떻게 생각해야 하는지 질문드립니다.

마지막으로 강의 21:03 부분에서 포인터 배열인 name의 출력결과가 원래는 주소인데 %s로 출력해서 문자열로 나오는 것으로 알고 있는데 주소가 문자열로 나오는 것은 아스키 코드의 값과 관련이 있는건가요?  그렇다면 제 생각에는 문자열의 주소를 저장해서 그 주소(어떤값)을 문자열로 출력한다면 아스키 코드값에 따라  주소에 해당하는 문자열이 나올것 같은데(즉 저장된는 주소값이 달라지면 문자열도 달라진다고 생각합니다)  정확하게 입력한 문자열이 나오게 되는 것이 이해가 되지 않습니다. 정확히 어떻게 %s로 주소값이 문자열로 출력되는 건가요?

(혹시 가능하시다면 추가적으로 이와 연관된 강의를 알려주시면 좋겠습니다.)

답변 1

답변을 작성해보세요.

0

강민철님의 프로필

강민철

2022.08.17

안녕하세요, 하나씩 답변 드리겠습니다.

1.  char aname [][15]과 같이 2차원 배열을 만들어 문자열 원소들을 초기화 해주었는데 이것이 어떻게 배열안에 저장되는지 이해가 되지 않습니다. 

 

첫번째 인덱스가 생략 가능한 이유는 "굳이 쓰지 않아도 알 수 있기 때문"입니다.

첫 번째 인덱스를 이차원 배열의 행, 두 번쨰 인덱스를 이채원 배열의 열이라고 생각해보세요.

아래와 같은 예시를 생각해보세요.

int a[3][2] = {1,2,3,4,5,6};

위 코드를 

int a[][2] = {1,2,3,4,5,6};

위 코드로 바꾸어도 어차피 행에는 3이 들어갈 것을 알 수 있잖아요?

컴파일러 또한 이렇게 유추할 수 있기 때문에 생략이 가능한 것입니다.

 

2. an = sizeof(aname) / sizeof(char[15])에서 사이즈를  sizeof(char[15])로 나누어 크기를 구했다고 하는데 잘 이해가 되지 않습니다. 하나의 원소의 크기로 나누어 사이즈를 구해야 되는 것이 아닌가요?

아니요, 하나의 원소의 크기가 아닌 배열 사이즈만큼 나누어야 합니다.

이것 또한 쉽게 생각하셔서 위와 마찬가지로 이차원 배열을 행과 열을 갖는 표와 같다고 생각해보세요.

하나의 원소로 나누는 것은 그 표의 하나의 셀 만큼 나누는 것과 같은데, 이는 아무 의미가 없겠죠?

char[15] 만큼 나누어야 행과 열을 갖는 aname을 char[15]만큼 나누겠다는 의미이므로 열만큼의 값을 얻을 수 있게 됩니다.

(그림을 그려보시며 이해해보시는 것이 어떨까 합니다)

 

3. 정확히 어떻게 %s로 주소값이 문자열로 출력되는 건가요? (주소가 문자열로 나오는 것은 아스키 코드의 값과 관련이 있는건가요?)

음.. 주소는 아스키와는 관련이 없습니다.

해당 문자열이 어떤 주소에 저장이 되었는지와 관련이 있습니다.

%s로 프린트하고자 하는 것은 "해당 문자열이 저장된 주소"라는 점에 유의해주세요.

 

상세히 답변하기 위해 노력했습니다만, 질문이 많으셨던 만큼 제 답변이 충분히 자세한지 모르겠네요.

혹시 궁금한 점이 있다면 댓글을 통해 말씀해주세요.

성종영님의 프로필

성종영

질문자

2022.08.18

친절한 답변 감사드립니다. 3번에서 %s로 프린트하고자 하는 것은 "해당 문자열이 저장된 주소"라는 것은 이해가 됩니다. 그런데 예를 들어서 "Aladdin"의 주소를 %s로 문자열로 출력하면 정확히 Aladdin으로 나온다는게 이해가 안됩니다. %u로 출력하면 어떤 숫자 주소가 나오는데 그거에 대한 문자열이 Aladdin이라는 것인가요? Aladdin 그자체가 주소로 나온다는게 이해가 잘 안됩니다 ㅠㅠ

강민철님의 프로필

강민철

2022.08.18

아아, 정확히 표현해드리자면,

%s로 출력하면 "해당 문자열이 저장된 주소"를 문자열로 출력되는 형식 지정자입니다.

그러니까, %s가 출력하는 대상은 char * 이지만 출력되는 결과는 문자열인 것이지요.

그래서 %u로 출력하면 주소가 나오는 것입니다.

성종영님의 프로필

성종영

질문자

2022.08.18

여러번 질문해서 죄송합니다. char* 포인터 배열에서 name[i]라는거 자체가 포인터 이므로 name[i]를 %s로 출력하면 "문자열이 저장된 주소"를 문자열로 출력하는것이다는 이해가 갑니다 그런데 주소가 정확히 Aladdin으로 나오려면 *name[i]와 같이 indirection으로 접근해야 Aladdin이 나와야 되는것이 아닌가요? 그런데 *name[i]과 같이 접근하면 컴파일 오류가 나던데 왜 그런지 모르겠습니다.

강민철님의 프로필

강민철

2022.08.20

(여러번 질문해주셔도 괜찮습니다^^) *name[i] 으로 접근하면 name의 요소에 두 번 접근하게 되기 때문(name 배열의 요소 - 그 포인터가 가리키는 값)에 이를 %s가 프린트하려고 하면 문자열의 시작 주소라고 이해하지 못할 것입니다. 그래서 오류가 떨어지는 것이 아닐까 합니다.

참고로, 혹시 이 부분을 아직 모르셔서 헷갈리시는 것이 아닐까 싶어 추가로 말씀드리자면, 문자열을 저장하는 변수(배열)은 이름 그 자체가 문자열이 저장된 주소를 의미합니다.

성종영님의 프로필

성종영

질문자

2022.08.22

문자열 그 자체가 저장된 주소이군요. 그런데 문자열을 저장하는 변수(배열) 이름 그 자체가 문자열을 저장하는 주소라는 것은 그냥 약속이라고 생각하면 되는 건가요?

강민철님의 프로필

강민철

2022.08.23

네 그렇습니다 :)