Re: 배열 형태 문자열 선언과 값 할당 헷갈립니다
, 도장_ 관리자님이 작성가능하면 단원을 순서대로 학습해주세요.
UNIT 39.1에서 그림 39-1을 보면 문자와 문자열의 저장 방식을 설명합니다.
"문자열 리터럴"은 기억 나는지요?
설명을 다시 인용하면...
문자는 변수 c1 안에 그대로 저장되지만 문자열은 변수 s1 안에 저장되지 않고, 문자열 리터럴이 있는 곳의 메모리 주소만 저장됩니다(소스 코드에 직접 입력한 "Hello"가 문자열 리터럴). 단, 이 문자열 리터럴이 있는 메모리 주소는 읽기 전용이므로 다른 문자열을 덮어쓸 수는 없습니다. 또한, 문자열 리터럴이 저장되는 위치는 컴파일러가 알아서 결정하므로 우리는 신경 쓰지 않아도 됩니다.
문자열 리터럴은 값 그 자체입니다. 컴파일러가 미리 할당한 공간에 값을 지정해서 넣어 두기 때문에 읽기만 할 수 있고 쓸 수는 없습니다.
배열은 읽기와 쓰기를 모두 할 수 있습니다. 배열에 문자열을 저장하는 것은 문제가 없습니다.
배열과 malloc 메모리 할당은 모두 메모리에 접근합니다. 대신, 이용하는 방식에 차이가 있습니다.
배열은 컴파일하기 전에 크기를 미리 정해야 합니다. 미리 정해진 크기만 쓸 수 있습니다.
scanf로 정수를 입력 받아서 배열의 크기를 정하는 코드는 작성할 수 없습니다.
int size = 0;
scanf("%d", &size);
char array[size]; // 비문법 코드
이런 형태의 코드는 불가능합니다.
동적 메모리의 이용은 malloc을 사용합니다. malloc을 이용하면 컴파일 과정에 메모리 크기를 정하지 않아도 됩니다. scanf에서 크기를 입력 받아서 malloc으로 원하는 크기를 할당할 수 있습니다. 예를 들어 메모장 프로그램을 작성할 때도 읽어들일 텍스트 파일의 크기를 미리 확인해서 필요한 만큼만 메모리를 할당하는 작업을 할 수 있습니다. 향후 실전 예제까지 진행하면 동적 할당이 예로 사용됩니다. UNIT 38.8 지뢰 찾기도 동적할당을 사용합니다.
함수 인자에 char*냐 char[]이냐는 오래된 논쟁입니다.
이 항목을 클릭하면 둘에 대해 이해할 수 있습니다.문자열을 scanf로 입력받을 때 배열을 인수로 저장하는 것은 배열의 주소가 전달되기 때문입니다. scanf는 입력받을 때 주소를 사용합니다. 정수형 변수에 대해 size가 아니라 &size처럼 사용하는 것도 변수의 주소가 필요하기 때문입니다. 이 역시 <C 언어 코딩 도장> 전체에서 왜 scanf는 정수 입력에는 &를 쓰는지까지 상세히 설명되어 있습니다. 처음부터 끝까지 완독하면 많은 걸 얻을 수 있을 겁니다.
구조체를 선언하면서 초기화하는 문법은 C 언어에서 제공하는 문법입니다.
단, Perseon 구조체의 멤버는 배열이므로 읽고 쓰는 데 문제가 없습니다.
좀 더 어려운 기술적인 내용으로는 C 언어는 컴파일 과정에서 프로그램의 섹션을 구분합니다. 이는 C 언어만 그런 게 아니라 실행 파일 포맷에 따른 문제입니다. .exe 확장자를 같는 binary executable(바이너리 실행파일)의 구조입니다.
코드에서 고정된 값을 값는 것들은 .data, .rodata 섹션에 배치됩니다. 문자열 리터럴은 고정된 상수이므로 .rodata 섹션에 배치됩니다. ro = read only의 약자입니다. 읽기 전용이라는 뜻입니다.
변수나 배열 같이 읽고 쓰는 동안 값이 바뀌는 것들은 .data 섹션이고, 스택 메모리를 이용합니다.
프로그램 코드는 .text 섹션에 배치됩니다. .code 섹션으로 쓰는 실행 파일 포맷도 있을 수 있습니다. 실행 파일 포맷은 Windows, Linux, macOS, Android 제각각 다릅니다.
기본은 비슷하지요.
malloc으로 동적 할당하는 메모리 공간은 힙(heap) 영역을 사용합니다. Linux에서는 .bss 섹션에 배치됩니다.
이와 같은 구조는 Linux에서도 확인할 수 있고, Windows용 GCC를 설치해서 확인할 수도 있습니다. Windows에서도 Linux Shell 설치가 가능합니다.
How is a binary executable organized? Let's explore it!
이와 같은 내용은 <컴퓨터 구조론>에서 대부분 학습하게 되고, <컴파일러> 수업에서 자세히 배우게 됩니다.
데이비드 패터슨의 <컴퓨터 구조 및 설계>가 유명합니다.
http://www.yes24.com/Product/Goods/16426341?scode=032&OzSrank=4
<컴파일러 입문>(오세만, 정익사)가 유명합니다.
컴퓨터 공학과이면 보통 이 두 과목은 C학점 폭격기로 유명합니다.
일반 프로그래머는 대부분 몰라도 상관 없습니다.
C 언어를 메인으로 시스템 프로그래밍쪽이 진로라면 컴퓨터 구조는 깊이 있게 학습하게 됩니다.