char *variable vs char variable[]

Two-Jay·2022년 12월 5일
0

단순히 printf()로 이 둘을 찍어보았을 때 차이는 없다. 하지만 둘은 선언되는 데이터 타입이 다르다.

char *variable로 선언된 str0는 char 타입 포인터에 상수문자열을 할당한 것이다. 따라서 상수인 읽기전용 데이터로 선언되었고, 이는 스텍 영역이 아닌 데이터 영역에 그 값이 저장되어있다는 것을 의미한다. 이에 문자 값의 변경이 불가능하다.

char variable[] 로 선언된 str1의 경우에는 문자들로 이루어진 단일 배열이다. 위의 경우와는 달리 스텍에 저장되어 있고, 따라서 값의 변경이 가능하다.

// ...
int main(void) {
    char str1[] = "Hello World";
    
    str1[2] = 'D';
    printf("%s\n", str1); // "HeDlo World"; 출력
    return 0;
}

따라서 둘은 사이즈도 다르다. 저수준 입출력 등 일부 함수에서 해당 변수의 사이즈를 parameter로 요구하는 경우도 있는데, 이 때 둘을 혼동하지 않고 잘 구분해서 써야한다. char variable[] 로 선언된 문자열에 sizeof() 매크로를 활용하면 문자열 전체의 길이를 가져올 수 있지만, char *variable는 그러지 못하고 포인터 자료형인 int의 자료형 크기만 가져오기 때문이다.

#include <unistd.h>

// fd, 문자열 주소와 사이즈를 받고 write로 출력하고 개행문자를 출력하는 함수
void write_endl(int fd, char const *str, size_t len) {
    write(fd, str, len);
    write(fd, "\n", 1);
}

int main(void) {
    char *str0 = "Hello World";
    char str1[] = "Hello World";

    // sizeof(str0)는 8, 'Hello Wo' 까지만 출력이 된다.
    write_endl(STDOUT_FILENO, str0, sizeof(str0));
    // sizeof(str1)은 12, 'Hello World' 모두 잘 출력이 된다.
    write_endl(STDOUT_FILENO, str1, sizeof(str1)); 
    return 0;
}

TCP/IP 소켓 프로그래밍 예제를 학습하다가, 둘의 차이점이 없는 줄 알고 혼동하여 썼었다. 이를 해결하기 위해 포인터로 선언했을 때는 strlen() 함수 등을 통해 정확한 길이를 확인한 후 출력했다.

#include <unistd.h>
#include <string.h>

void write_endl(int fd, char const *str, size_t len) {
    write(fd, str, len);
    write(fd, "\n", 1);
}

int main(void) {
    char *str0 = "Hello World";

	// 잘 출력이 되는 것을 확인할 수 있다.
    write_endl(STDOUT_FILENO, str0, strlen(str0)); 
    return 0;
}
profile
해본 것을 말하고 싶습니다.

0개의 댓글