C언어 주로 constant와 관련된 질문입니다.
1) constant와 literal의 관계는?
상수가 리터럴을 포함하는 개념으로 이해하고 있습니다. 따라서 상수는 항상 리터럴이 될 수 있지만, 리터럴은 상수가 될 수 없는게 맞는건가요? 참고로 프로그램 소스에서 글자 그대로의 값(문자, 문자열 포함)을 리터럴로, 리터럴에서 자료형이 추가되어 메모리에 저장된 값이 항상 일정한 것을 상수라고 이해하고 있습니다.
2) constant는 정말 변경할 수 없나요?
흔히 상수를 변하지 않는 수, 항상 일정한 수라고 설명하잖아요? 그럼 우리가 일반적으로 아는 상수는 컴파일러 역시 구분할 수 있을테고, 그런 상수는 프로그램 실행 중에 운영체제가 변하지 않도록(항상 일정 하도록) 소프트웨어적으로 보호 해주는게 맞을까요? 그럼 결국 상수는 물리적으로(하드웨어적으로) 변경될 수 있는건 맞나요? 상수가 저장되는 물리적 장치가 일반적으로 RAM 이니까요.
3) C언어(C표준)에서 말하는 메모리 구조란?
흔히 C언어의 메모리 구조라면서 크게 코드 영역, 데이타 영역, 힙 영역, 스택 영역으로 구분하잖아요? 그런데 이게 C표준에서 요구하는 내용을 만족시켜서 나온 결과물일 뿐인거죠? C표준에서는 코드 영역, 데이타 영역, 힙 영역, 스택 영역 이라는 용어를 사용하지 않고 각각의 영역에 대한 최소한의 요구사항만 나열한거 뿐인거죠? 마지막으로 C언어를 지원하는 환경이 위의 4개의 영역을 구분하고 제공하기만 한다면 추가적으로 다른 별개의 영역(예를들어 보조 영역)을 가져도 문제 될건 없는거죠?
굉장히 깊이 있는 질문이로군요.
C언어 표준을 여기저기 들춰봐야만 답변할 수 있는 질문들도 있는 것 같은데, 제가 (익명이라 식별은 안 되겠지만) 그런 종류의 답변을 여기서 줄곧 달아 드렸습니다만 부득이 개인 사정으로 이번주엔 시간이 없습니다.
다음 주 쯤에 시간 내서 답을 드리지요. 물론 저보다 더 뛰어나신 고수께서 먼저 답을 드린다면 전 그냥 조용히 물러날겁니다.
흠. 그 전에 부탁드릴 게 있는데, 질문자님의 C언어 및 컴퓨터 시스템(CPU, OS, 컴퓨터구조 등)에 대한 배경지식이 어느 정도인지 밝혀 주신다면, 수준에 맞는 답을 드리는 데 도움이 많이 될 것 같습니다.
C언어를 학습중에 있는 초보입니다.
언급해주신 CPU, OS, 컴퓨터 구조 과목을 따로 공부한 적은 없습니다. C언어를 학습(정확하게는 복습)하면서 시스템 관련 부분이 종종 궁금했었고 그때마다 관련 부분만 찾아서 읽어보는 정도입니다.
천천히(속으로는 최대한 빨리..) 답변 남겨주셔도 괜찮습니다.
익명님보다 더 고수라서 해서 초보자인 저를 더 잘 이해시켜줄 것 같지는 않습니다(제 시각에서 바라볼때는 모든 분이 남겨주시는 답변이 어렵기는 마찬가지 일테니까요 ㅎㅎ).
그런 의미해서 한분 한분의 답변이 소중합니다. 조용히 물러나진 말아주세요..ㅠ
constant 를 자료형이 부가된 constant
constant 를 자료형이 부가된 constant literal 이라 볼 수는 있지만, 반드시 메모리에 저장된다는 보장은 없습니다.
메모리 참조 코드가 없을 때는 컴파일러가 컴파일 시에 constant literal 로 처리하고 끝낼 수도 있습니다.
C 는 C++ 과 달리 strongly typed 언어가 아니기 때문에 constant 가 메모리에 저장된다면 널 포인터를 적당히 조작하여 변경할 수 있는 방법이 있지 않을까 생각되지만, 확실하지는 않으니 테스트해 보시길.
2) constant는 정말 변경할 수
2) constant는 정말 변경할 수 없나요?
C/C++ 언어의 일반적인 방법으로 사용한다면 한번 constant로 쓰면 바뀔일이 없습니다. 프로그램 도중에 바꾸지 말라고 지원하는 기능이니까요. 하지만 이리저리 casting 하다보면 바꾸는 방법이 있기도 합니다. 이러한 것은 흥미나 궁금증 해소 차원에서 하는 것이지 정상적인 프로그래밍 방법이 아닙니다.
3) C언어(C표준)에서 말하는 메모리 구조란?
elf 나 exe 형태로 생성되어 실행만 되면 어떤 메모리 구조든 유저가 상관할 바 없습니다. 메모리 구조는 컴파일러와 링커가 결정합니다. 이 둘의 역할은 가장 효율적으로 프로그램이 구성되어 실행되게 하는 것입니다. C/C++ 언어 자체는 이를 전혀 상관하지 않습니다.
...
문법 전문가는 아닙니다만... (C 언어는 워낙 표준이 어렵고 함정이 많아서 함부로 말하기가 조심스럽습니다 -_-)
1) constant는 *변수*에 붙는 속성입니다. 이를 테면 const int이면 값을 바꿀 수 없는 정수, const char *이면 값을 바꿀 수 없는 문자를 가리키는 포인터, char *const이면 (값을 바꿀 수 있는) 문자를 가리키지만 값을 바꿀 수 없는 포인터, 뭐 이런 거죠.
반면 literal은 C 언어 *소스 프로그램*에 등장하는 값입니다. 경우에 따라 literal이 const 속성의 값으로 바뀌기도 하지만 (예를 들면 문자열) 기본적으로 서로 다른 문맥에서 쓰이는 개념입니다.
2) const 변수를 변경하는 건 아마도 표준에서 정의되지 않은 동작으로 알고 있습니다만... 다시 말해 제대로 동작한다는 보장이 없고, 에러가 난다는 보장도 없습니다. 무슨 일이든 일어날 수 있습니다.
1) constant와 literal의 관계는? 짧게
1) constant와 literal의 관계는?
짧게 말하자면 '그런 것 없습니다'
프로그래밍 언어론 상의 개념 같은건 모르므로 그냥 C99 기준으로만 말씀드리자면...
constant는 그냥 lexical element중의 하나이며, token 중의 하나일 뿐으로, 그 형제는 keyword, identifier, string-literal, punctuator가 있습니다.
constant는 자료형이나 메모리와 같은 개념과는 상관없는, C코드를 자를 때 발생하는 token의 한 종류일 뿐입니다.
적어도 C99상으론 그렇습니다.
literal이란?
C99 기준으로는 literal과 관련된 용어로는 string literal과 compound literal 딱 두개가 전부입니다.
두개 다 메모리 상에 실존하는 object로서 행동하며, constant와의 관계는... 별로 관계랄건 없습니다.
constant와 전혀 별개의 개념이라고 생각하시는게 좋고,
사실 C99기준으로는 string-literal과 compound literal이 뭔가 literal이라고 함께 묶일만한 개념도 아닙니다.
왜냐하면 string-literal은 lexical element인데 비해 compound literal은 postfix operator로서 서로 분류 계층이 전혀 다릅니다.
2) constant는 변경할 수 없나요?
constant는 변역 단계 7~8에서 token 단위로 소스 코드를 끊을 때나 쓰는 개념이므로, 이 단계에서는 '변경'같은 개념 자체가 없습니다.
그럼 constant의 실제 물리적 형태는 어떤 것이냐... constant 자체가 무척이나 추상적 개념이므로 여기에 실물을 기대하는건 무리입니다.
변경 가능 불가능을 따지는건 일단 타입과 object를 획득한 다음에나 가능할텐데, constant를 세고 있는 단계엔 아직 그런게 없습니다.
constant는 허공에 뜬 뜬구름 같은 단지 '의미'와 '개념'일 뿐이며, 이게 실체를 갖는건 이제 객체에 해당 값이 대입이 되면서 부터지요.
3) C언어에서 말하는 메모리 구조란?
힙이고 스택이고 아무 것도 없습니다. C의 메모리 구조는 그냥 평평한 광활한 대지 위에, byte(일반적인 8bit가 아닌, 문자 셋을 담을 수 있는 메모리 공간의 최소 단위) 단위로 주소값이 붙어있는 형태로, 여기에 정렬제한 이나 volatile 정도가 붙어있는게 고작입니다.
C언어에는 스택이란 개념 자체가 없습니다. 물론 스택 구조를 염두에 둔 설계이긴 합니다.
C언어에서는 지역변수가 스택에 쌓이고 변수에
C언어에서는 지역변수가 스택에 쌓이고
변수에 역순으로 메모리에서 할당/해제되는데
어떤 의미로 적으신건지 잘 모르겠습니다.
질문자의 질문을 다시 한번 읽어보십시오. >
질문자의 질문을 다시 한번 읽어보십시오.
> C언어(C표준)에서 말하는 메모리 구조란?
표준 문서에는 말씀하신 그런 내용이 없습니다.
흔히 말하는 메모리 구조-힙, 코드따위-는
흔히 말하는 메모리 구조-힙, 코드따위-는 운영체제에서 나온 개념인 것은 알고 있으나
(밑에 제 답변에도 그렇게 서술합니다)
지역변수(automatic variable)의 스택 개념 조차 없는지는 찾아보고 알았습니다.
ISO/IEC 9899:201x 문서에서는 stack이라는 단어가 하나도 검색이 안되는군요.
감사합니다. 제 입맛에 딱 맞는 답변 내용이였습니다.
누구신진 모르겠으나, 제 수준을 고려해서 쉽게 설명해주신점 대단히 감사드립니다^^
# 추가된 내용 #1
string literal이 토큰이 맞나요?
=> c언어의 토큰에 string literal을 명시하지 않은 글 때문에 혼란스러워서 질문 드렸던 내용이였는데,
해당 글을 천천히 읽어보니 상수에 string literal까지 포함시켰더라구요..
string literal은 C99 기준으로,
string literal은 C99 기준으로, 번역단계에서는 토큰이고, 이것이 번역후에는 char형 배열이 됩니다. (const형 아님)
그리고 C언어 특유의 기묘한 배열->포인터주소 규칙에 의해서, 결론적으로는 그 첫번째 원소를 가리키는 포인터 주소값이 됩니다.
string literal은 constant가 아닙니다.
token이란 점에서 constant의 형제이긴 하군요.
string literal이 문자열 상수로 번역되기 때문에 이걸 constant로 묶어서 생각하는 사람들이 많은데,
포함관계라기 보다는 둘 다 token에 속하는 서로 다른 형제입니다.
2) constant는 정말 변경할 수 없나요?
2) constant는 정말 변경할 수 없나요?
시스템에 따라 다릅니다. Data 영역에 있는(전역변수)의 경우
운영체제가 상수성을 보장해줄 수 도 있습니다.
하지만 이것도 시스템에 따라 다릅니다.
3) C언어(C표준)에서 말하는 메모리 구조란?
C 언어만의 메모리 구조가 아닙니다. 운영체제에서 나눈 개념에 더 가깝습니다.
구분한 이유는 운영체제가 메모리를 효율적으로 관리하기 위해서 입니다.
https://www.google.co.kr/url?sa=t&rct=j&q=&esr를c=s&source=web&cd=1&ved=0ahUKEwit2MPD-YLOAhXFnJQKHRLxAYoQFggdMAA&url=https%3A%2F%2Fwowhacker.org%2Fboard.php%3Fbid%3D174%26bs_type%3D%26bs_str%3D%26cate%3D0%26pg%3D0%26mode%3Dfiledown%26puid%3D274235%26uid%3D41&usg=AFQjCNEFuciR6sIHnNk_h63Rmrs0SG22-w&sig2=hEQ3RAcQsE7Lomj6QRRTSA&bvm=bv.127521224,d.dGo&cad=rjt
여기에 잘 설명되어 있네요.
"프로세스가 4GB 의 메모리를 사용할 수 있는 것은 맞지만, 4GB 의 메모리를 모두
가지고 있는 것은 아니다. 일반적으로 프로세스가 생성될 때에는 프로그램의 실행에 필요한
최소한의 Code, Data 만이 메모리에 적재된다. 메모리의 효율성을 증가시키고, 효과적인
실행을 위함이다. 운영체제는 최소한의 것들만 가지고 필요할 때마다 추가시키는 메커니즘을
사용한다."
PS.
각 영역에 구체적으로 어떤 코드가 들어가는지 C코드에 비유하면,
코드 영역 - 함수같은 루틴.
데이타 영역 - static 변수(전역 변수 포함)
스택 - 지역변수
힙영역 - 동적할당 변수
댓글 달기