본문 바로가기

공부/c언어

문자열 상수

반응형

char* str="qwerty";

 

//str이 라는 포인터문자열의 첫글자주소를 가리키게 되잖아요 그러면 qwerty라는 문자열은 어디에 저장되는건가요 ?

// 여기에 대한 답은 문자열상수는 선언시 컴퓨터의 메모리 어딘가 읽기 전용 영역에 연속하여 메모리가

// 생성됩니다. 이렇게 생성된 주소를 포인터가 맨앞의 주소를 참조하는것입니다.


// 문자열 상수입니다. 문자열을 이와 같이 선언하면
// 배열이나 문자열이 묶음 자료 전체를 나타내는 경우는 sizeof 연산자와 & 연산자를 사용하는 2가지 경우 뿐이고
// 나머지는 모두 첫번째 자료가 저장된 메모리의 주소로 사용됩니다.
// 문자열 상수는 특별히 읽기 전용 영역에 저장되어 수정할 수 없도록 하고 있습니다. 같은 문자열이 여러 번 사용될 때,
// 하나의 문자열만을 만들어 여러 번 사용할 수 있도록 최적화하기 때문입니다.
//즉 읽기 영역에 저장된 것을 임의의로 변경하려 하기때문에 에러가 발생하는거입니다.

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

http://yhjeong89.blog.me/100136816366

 

char *str = "string";

char arr[] = "string";

이 둘이 완전히 같은 것일까요?

그렇지 않습니다. 다시 메모리를 그려서 확인을 해보겠습니다.

 

 

문자열 포인터의 모습입니다. 포인터 변수가 문자열의 처음 부분 주소를 가지고 있어서 가리킬 수 있습니다.

 

문자열 배열의 모습입니다. 감이 잡히시나요?

문자열 포인터는 말 그래도 포인터입니다. 그렇기 때문에 포인터 변수를 위한 공간이 있어야합니다.

그러나 문자열 배열은 그렇지 않습니다. arr은 그저 이름일뿐 메모리 공간을 소유하지 않습니다.

str도 메모리 주소를 가리키고 arr도 메모리 주소를 가리킵니다.

그러나 str은 메모리 공간 안에 주소가 저장이 되어있어서 그것을 로드하는 것이고

arr은 그 자체로 &arr[0]을 나타내는 것이지 별도로 메모리 공간을 가지지 않습니다.

또한 중요한 차이점으로는

문자열 포인터를 선언하고 초기화 하는 것은 문자열 상수를 의미하고

문자열 배열을 선언하고 초기화 하는 것은 문자열 변수를 의미합니다.

즉 포인터에게는 아래와 같은 수정이 불가능 하다는 것입니다.

str[1] = 'a'; //상수이므로 이런 방법으로는 변경 불가능

arr[1] = 'a'; //변수이므로 이런 방법으로 변경 가능

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////

http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040101&docId=63672518&qb=66y47J6Q7Je0IOyDgeyImCDshozrqbg=&enc=utf8&section=kin&rank=3&search_sort=0&spq=0&pid=RS1lMF5Y7uNssv3CrolsssssssG-360990&sid=UV1cw3JvLDIAAFigXqk

자동 변수라는 것은 함수가 불려질 때에 콜스택에 일괄적으로 생성되고

함수가 종료되면 없어집니다.

 

동적으로 할당된 메모리, - 직접 해제하기 전까지 보존됨

전역변수, - 프로그램 종료 전까지 보존됨

main함수에서 정의된 변수, - main 함수가 종료되기 전까지는 확실히 보존됨

make_name() 함수에서 정의된 정적변수 - 정적변수는 함수가 종료되어도 보존됩니다.

초기화 등에 사용 가능한 문자열 상수 - 문자열 상수는 절대적으로 보존됩니다(프로그램에 종료되어야 삭제됨). 변경불가

이중에서 동적 할당 메모리는 사용이 끝나고 반드시 해제해주어야 하므로 비추합니다.

내용추가 - 이해를 돕기 위해 예를 추가했습니다.

char name[20] = "홍길동"; // 전역변수~ 죠. 언제나 포인터로 넘길 수 있음.

void main ()

{

char name1[20] = "박명수"; // main함수에서 정의한 자동변수.

// main함수가 종료하기 전까지만 살아있습니다.

// 하지만 main함수의 종료는 프로그램종료를 뜻하죠?

static char name2[20] = "박명수"; // 정적(static) 변수는 언제나 살아있습니다.

// 전역변수도 정적변수의 일종입니다.

}

char *func1()

{

static char name3[20] = "자린고비"; // 정적변수는 언제나 살아있습니다.

char name4[20] = "구두쇠"; // 이 자동변수는 func1함수가 종료되면 죽습니다.

// 쉽게 말해서 func1함수가 호출시에 땅을 샀다가

// 종료할 때 팔아버립니다. 그러면 그 땅에 재개발이 되었다면?

// 거기 있던 건물은 찾을 수 없겠죠.

char *name5 = "핫바지"; // 상수는 변경불가능 소멸 불가능(프로그램에 종료되어야 삭제됨)

// name5 포인터 변수는 자동변수(func1함수와 운명을 같이하는)지만,

// "핫바지" 문자열상수입니다. 절대로 없어질리 없고 변경 불가능한

// 국가 관청같은 것이죠.

return name4; // 이것은 무의미하죠. 리턴 후에는 name4의 공간이 없어집니다.

// name4 이외의 다른 값은 가능합니다.

// 또 다른 방법으로는 함수의 인자로 값을 전달할 메모리를 지정받는 것이죠.

// 이 함수가 종료되어도 전달받은 메모리는 살아있습니다.

}

반응형