작성
·
466
1
강의 10: 21부분입니다.
교수님께서 61번째 문장 dest = "Start something"; //Error
에서 에러가 발생한다고 말하셨는데, 어째서 에러가 발생하게 되는 것인지 잘 모르겠습니다.
error C2106: '=': left operand must be l-value
빌드를 실행해보면 왼쪽은 l-value로서 작동해야한다고 합니다.
이미 공간(주소)을 할당받은 배열 dest가 있고,
배열의 이름 dest, 즉 포인터에다가, (수정불가능한/읽기만 가능한 프로그램 코드에 있는) "Start something"이라는 문자열의 주소를 대입함으로서 그걸 수정(?)하려 시도했기에 에러가 발생하는걸까 싶기도 하고.. 머릿 속의 개념이 꼬여버렸습니다.
※그치만 이것이 안되는 경우는,
'포인터로 정의한 문자열이 있을 때 포인터를 통해 인덱싱하여 값을 수정하려고 했을 때" 문제가 발생하는 경우였습니다.
이번 dest = "Start something"; //Error
의 경우에 해당하진 않을 것 같습니다.
답변 2
1
안녕하세요? 오랫만에 이 질문에 대해 다시 질문이 들어와서 봤는데, 아래 답변에 잘못된 부분이 있어서 수정하겠습니다.
gcc에서 아래 코드를 컴파일하려고 시도하면
char dest[100] = "";
dest = "Do Something";
error: assignment to expression with array type
배열에 대입하려고 시도했다는 에러가 발생합니다.
C언어에서는 배열의 값을 바꾸고 싶을때 간단한 대입을 사용할 수 없습니다.
strcpy, memcpy로 메모리 블럭을 복사하거나 아니면 for문으로 하나씩 대입해야 합니다.
우리 입장에서는 그냥 좀 해주지 싶겠지만 C언어를 설계하신 분들 입장에서는 사용자가 해야할 일이라고 판단하신 것으로 추측됩니다.
반면에 초기화할때는 가능합니다.
char dest[100] = "Do Something"; // <- 이건 가능
그 다음은 제가 답변드리면서 헷갈렸던 사안인데,
char *a = "Do Something";
a[0] = 'A'; // <- read only 영역을 건드림
printf("%s\n", a); // <- 아무것도 출력되지 않음 (출력 될 수도 있으나 알 수 없음)
이 부분은 강의 다른 부분에 설명이 있었을텐데 "Do something"은 프로그램의 일부로써 read-only 읽기 전용 영역에 들어있기 때문에 변경 시도가 어떤 문제를 만드는 것입니다.
반면에 아래 코드는 정상작동합니다. 왜냐하면 dest 배열이 스택에 수정가능한 메모리를 갖고 있고 거기에 "Do something"이 복사되어 있는 상황이라서 dest[0]으로 한 글자를 수정할 수 있습니다.
char dest[100] = "Do Something";
dest[0] = 'A';
printf("%s\n", dest);
다시 원래 질문글로 돌아오면,
error C2106: '=': left operand must be l-value
VS의 컴파일러에서 제공해주는 에러 메시지가 모호했던 것 같습니다.
저는 문법 확인용으로 gcc를 급하게 사용하고 싶을 때 온라인 컴파일러를 사용합니다. 아래 캡쳐 화면 참고하세요.
0
위에 수정 답변 올렸습니다.
이런 문제는 에러만 곧이곧대로 보면 이해가 어려운게 정상입니다. 사실 이건 우리가 논리로 따져서 왜 안해주냐고 따질 수 있는 것이 아니라 그냥 컴파일러가 안해주도록 만들어져 있는 것입니다. 그렇다고 안해주는 이유가 아예 없는 것은 아닌데 "Start something" 같은 문자열은 컴파일 할 때 프로그램에 탑재됩니다. 따라서 컴파일 타임이 아니라 런타임에 내용을 바꾸고 싶다면 한글자씩 바꾸는 방식으로 사용하라고 의도적으로 그렇게 정해놓은 것입니다.
예) dest[0] = 'A';