C언어 문자열 선언에 관한 질문입니다.
요즘 스타일에 대한 관심이 많어서리 이런 질문을 많이하게 되네여 ^^; 초보다보니 모르는것 투성이-_-;
C언어에서 문자열을 사용하고자 합니다.
예를 들어
char *string;
이렇게 선언하고 malloc로 적정 공간을 할당받아 사용하는 방법이 있고,
char string[SIZE];
이런식으로 좀 큰 배열을 할당받아서 사용하는 방식이 있잖아요.
물론 둘의 내부로직은 다르다는 것을 알고 있습니다.
궁금한 것은 여러분들은 문자열을 선언하고 처리할때에 어떻게 선언하고 관리하는지 궁금해서 입니다.
위 두 방식은 함수로 인자를 넘길때나, 관련 연산등을 처리할때 내부 함수의 로직이 완전히 달라지기 때문에 중간에 수정하기도 뭐해서 용도에 맞게 처음부터 잘 선언하는 것이 중요할 것 같습니다.
장,단점과 어떤 용도시 어느것을 써야할지 알려주시면 감사하겠습니다. 관련 문서도 알려주시면 더욱 감사하구요 ^^:
제가 아는 짧은 지식은 char*방식은 길이가 유동적이라는 것과, 문자열 함수를 쓰기에도 유리하고... 대신 배열은 조금 안전하고, 함수 stack에서 허용하는 작은 크기라면 훨씬 빠르지 않을까 합니다.
cf) 참고로 지금 shell을 짜고 있구요. 입력 문자들을 parsing해서 해당 종류에 따라서 연산을 처리하고 있습니다. 따라서 함수에 문자열들이 인자로 자주 이동하는 형편입니다.
질문2) 어느것을 써도 상관없을시에는 어떤 방식을 쓰는게 좋을까요? 그리고 하나의 프로그램에서는 하나의 방식으로 통일하는게 좋지않을까요? 혼란스럽지 않게.....
혹시나 해서 하는 말이지만, C에서는 일차원 배열을 함수의 매개변수로 넘
혹시나 해서 하는 말이지만, C에서는 일차원 배열을 함수의 매개변수로 넘기는 방법이 없습니다. 함수 선언 및 정의에서 array of ... 형태의 매개변수는 모두 pointer to ... 형태로 변환되어 처리됩니다. 따라서 char *str; 이나 char str[SIZE]; 나 같은 방식으로 처리 가능합니다.
또한 수식(expression)에 쓰인 배열 이름은 세가지 경우(sizeof연산자의 피연산자, &연산자의 피연산자, char형 배열의 초기화)를 제외하고는 항상 그 자신의 첫번째 원소를 가리키는 포인터 주소값으로 자동 변환됩니다. 즉 대부분의 경우 배열 이름 = 포인터 주소값이라 봐도 무방하죠.
free()만 주의하면 두가지 사이에 차이점은 없습니다.
저라면 다음과 같이 하겠습니다.
1. 필요한 메모리 크기가 미리 고정되어 있는 경우라면 free()의 귀찮음이 없는 char str[SIZE] 쪽을 선호한다.
2. 그렇지 않은경우 char *str = malloc(1234);를 사용한다.
제가 착가했네요..
답변감사하구요.
제가 착가했네요.. ^^; 둘다 첫 주소가 넘어가는 방식이지요.
단지 스타일상 함수를 구현할때
void proc(char *string);
void proc(char string[]);
이런 두가지 방법이 다 가능하잖아요.
첫번째 방식에서는 *(string + i) 이런식으로 사용하고
두번째 방식에서는 string[i]이런식으로 안에서 사용한다면
어떤 식으로 쓰는 것이 깔끔할지 궁금하네요. 어차피 string[i] 도 *(string + i)이기는 하지만..... (그냥 스타일상의 질문입니다. :) )
그리고, 2차원 배열의 경우는 다르지 않나요?
여러개의 문자열을 저장할 경우 char *aaa[ROW]로 선언하고 하나씩 malloc하는 방식이 좋을지 아예 2차원 배열 char aaa[ROW][COL]로 선언하고, 시작주소만 가져다 쓰는 것이 좋을지도 의문이네요. 물론 각 문장이 가변길이라면 전자의 경우가 좋겠지만, 크기가 그다지 크지 않다면 후자가 수행속도도 빠르고 사용하기도 편하지 않을까요?
(Code Complate 책에서 왠만하면 배열로 선언하고 사용하라고 나와있는 부분을 얼핏본것도 같구요).
써놓고 보니 별거아닌 문제 같기는 하지만, 그래도 어느정도 코딩 스타일을 잡아가고 싶어서 하는 질문입니다. :)
void proc(char *string);void proc(char
void proc(char *string);
void proc(char string[]);
위의 두 줄은 완벽히 동일한 선언입니다. 위에서 말한 대로 함수 선언 및 정의에서 array of ... 형태의 매개변수는 모두 pointer to ... 형태로 변환되어 처리됩니다. 참고로 저는 전자 쪽을 선호하는 편입니다.
함수 내부에서는 string[i] 쪽이 가독성이 높고 쓰기 편하다는 이유로 그쪽을 선호합니다. 하지만 어차피 *(string + i) 나 string[i]나 완벽히 동일한 수식이므로, 프로그래머가 판단할 일입니다.
문자열을 처리할때는, 메모리 공간의 낭비라는 면 보다는 나중에 수정해야 하는가 말아야 되는가 하는 점을 먼저 따져야 되지 않나 싶군요.
1. 문자열을 나중에 전혀 수정할 필요가 없다 -> array of pointer to char 만들어서 각각 문자열 상수를 가리키게 한다. 가장 쉽고 간단.
char *strs[] = { "msg1", "msg2", "msg3" };
2. 문자열이 변경될 수 있지만 그 최대길이에는 한계(MAX_SIZE)가 있다.
char strs[3][MAX_SIZE] = { "msg1", "msg2", "msg3" };
3. 문자열이 차후에 변경될 수 있다. 2번처럼 할 경우 뒤에 남는 공간이 아깝다. 혹은 문자열이 변경될 때 그 최대길이에 제한이 없다. -> 일일이 malloc로 할당해서 그 안에 strcpy로 복사해서 넣는다.
반드시 3번처럼 해야 되는 경우가 있긴 하지만, 그런 경우에는 C라고 해도 C++의 클래스를 흉내내어 추상적 데이터형을 만들어 처리하는 것이 오히려 더 나을 것입니다.
답변 감사합니다 ^^
답변 감사합니다 ^^ 많은 도움이 되었습니다.
같은 내용인데 책들마다 다르다 보니, 제 생각이 스타일이 과연 괜찮을지 의문이 들었었는데 이제 어떻게 다뤄야 할지 개념이 잡혔습니다--
Re: 제가 착가했네요..
전자의 경우에 aaa는 char **이 되고 후자의 경우에는 aaa는 char *이 되는 점도 다른점이겠군요.
블로그: http://turtleforward.blogspot.com
댓글 달기