배열의 이름은 값을 바꿀 수 없는 상수 형태의 포인터 이다.

#include <stdio.h>

int main(void)
{
    int arr[] = {0,1,2};
    printf("배열의 이름 : %p\n", arr);
    printf("첫 번째 요소 : %p\n",&arr[0]);
    printf("두 번째 요소 : %p\n",&arr[1]);
    printf("세 번째 요소 : %p\n",&arr[2]);
    return 0;
}
/* output : 
배열의 이름 : 0061FF14
첫 번째 요소 : 0061FF14
두 번째 요소 : 0061FF18
세 번째 요소 : 0061FF1C
*/

int형 배열의 요소간 주소 값의 차는 4바이트 인것을 확인할 수 있다. 또한 모든 배열 요소는 메모리 공간에 나란히 할당됨을 알 수 있다. 배열의 이름은 배열의 시작 주소 값을 의미하고, 그 형태는 값의 저장이 불가한 상수이다. 

 

배열의 이름도 포인터이기 때문에 배열의 이름을 피연산자로 하는  * 연산이 가능하다.

#include <stdio.h>

int main(void)
{
    int arr1[] = {1,2,3};
    double arr2[] = {1.1,2.2,3.3};

    printf("%d %g\n", *arr1, *arr2);
    *arr1 += 100;
    *arr2 += 120.5;
    printf("%d %g\n", *arr1, *arr2);
    return 0;
}
/* output: 
1 1.1
101 121.6
*/

배열의 이름이 가리키는 것은 배열의 첫번째 요소이기 때문에 배열의 이름을 대상으로 *연산을 하면 배열의 첫번째 요소에 접근된다.

 

#include <stdio.h>

int main(void)
{
    int arr[] = {10,20,30};
    int *ptr = &arr[0];

    printf("%d %d\n", ptr[0], arr[0]);
    printf("%d %d\n", ptr[1], arr[1]);
    printf("%d %d\n", ptr[2], arr[2]);
    return 0;
}
/* output : 
10 10
20 20
30 30
*/

위 코드와 같이 포인터를 배열의 이름처럼 사용할 수도 있다.

'Language > C, C++' 카테고리의 다른 글

[C] 문자열 포인터  (0) 2020.12.18
[C] 포인터 연산  (0) 2020.12.17
[C] 포인터 변수  (0) 2020.12.16
[C] 1차원 배열(2)  (0) 2020.12.14
[C] 1차원 배열(1)  (0) 2020.12.12

변수는 메모리 상에 저장되고, 포인터 변수는 메모리의 주소값을 저장하기 위한 변수이다.

#include <stdio.h>

int main(void)
{
    int num = 9;
    int *pNum;      // 포인터 변수 pNum 선언
    pNum = &num;    // pNum에 num의 주소값 저장

    printf("%d\n", pNum);   // 메모리 주소 출력
    printf("%d\n", *pNum);  // 메모리 주소에 저장된 값 출력

    *pNum = 20;     // pNum이 가리키는 주소에 저장된 값을 20으로 변경
    printf("%d\n", num);
    return 0;
}
/* output : 
6422296
9
20
*/

*으로 포인터 변수를 선언할 수 있고, &연산자는 피연산자의 주소값을 반환하는 연산자이다. &연산자의 피연산자는 변수여야 한다. 

*연산자는 포인터가 가리키는 메모리 공간에 접근할 때 사용하는 연산자이다. 

 

포인터 변수의 크기는 32비트 시스템에서는 주소값을 32비트로 표현하기에 4바이트이고, 64비트 시스템에선 주소값을 64비트로 표현하기 때문에 8바이트다.

'Language > C, C++' 카테고리의 다른 글

[C] 포인터 연산  (0) 2020.12.17
[C] 포인터와 배열  (0) 2020.12.17
[C] 1차원 배열(2)  (0) 2020.12.14
[C] 1차원 배열(1)  (0) 2020.12.12
[C] 재귀함수  (0) 2020.12.10

C에서는 다음 코드와 같이 배열에 문자열을 저장할 수 있다.

char str[14] = "Good morning!";
char str[] = "Good morning!";

"Good morning!"은 공백 포함 13자 이지만 배열을 선언할때 길이를 14로 설정해야 하고 배열의 길이를 생략해도 길이는 14로 결정된다. 문자열의 끝에는 '\0'이라는 특수문자(escape sequence)가 자동으로 삽입되기 때문이다. 따라서 char형 배열로 문자열을 선언할 경우 특수문자 '\0'이 저장될 공간까지 고려해야 한다. '\0'은 널(null)문자 라고 한다.

#include <stdio.h>

int main(void)
{
    char str[] = "Good morning!";
    printf("size of str array : %d \n", sizeof(str));
    printf("char Null print : %c\n",str[13]);
    printf("int Null print : %d\n",str[13]);
    return 0; 
}
/* output : 
size of str array : 14
char Null print : 
int Null print : 0
*/

위 코드와 같이 널문자를 문자열로 출력하면 공백이 출력되고, 정수형으로 출력하면 0이 출력된다. 널문자의 아스키 코드 값은 0임을 알 수 있다. 

int main(void)
{
    char nu = '\0';	// 널문자 저장
    char sp = ' ';	// 공백 저장
    printf("%d %d", nu, sp);	// output : 0 32
    return 0;
}

위 코드와 같이 널문자의 아스키코드 값은 0이고 공백문자의 아스키 코드값은 32이기 때문에 문자열로 출력했을때 같아 보일지라도 널문자와 공백 문자는 다른 값이다.

 

다음과 같이 서식문자 %s를 사용하여 scanf()함수를 이용해 문자열을 입력받을 수 있다.

#include <stdio.h>

int main(void)
{
    char str[50];
    int idx = 0;

    printf("문자열 입력 : ");
    scanf("%s", str);   // &연산자를 사용하지 않음
    printf("입력받은 문자열 : %s\n", str);

    printf("문자열 단위 출력 : ");
    while(str[idx] != '\0')
    {
        printf("%c", str[idx]);
        idx++;
    }
    printf("\n");
    return 0;
}

정수형과 같은 데이터를 저장하는 변수 앞에는 &연산자를 붙이지만, 문자열을 입력받는 배열의 이름 앞에는 &연산자를 붙이지 않는다. 

scanf()함수로 입력받은 문자열의 끝에도 널문자가 저장된다. C에서 표현하는 모든 문자열의 끝에는 널문자가 저장된다. 만약 다음 코드와 같이 널문자가 없으면 문자열이 아니다. 문자들을 저장한 배열일 뿐이다.

char arr[] = "{'h','e','l','l','o'};

문자열에서 끝에 널문자가 저장되는 것은 메모리상에서 문자열은 이진 데이터로 저장되어 있기 때문에 문자열의 시작과 끝을 구분해주기 위해서다. 0번 인덱스가 시작위치이고, 널문자가 끝나는 위치이다. 

scanf()함수에 공백을 포함한 문자열을 입력하게 되면 출력값은 공백 이전의 문자열만 출력되게 된다. scanf()함수는 공백을 기준으로 데이터를 구분짓기 때문에 "Hello World!"를 입력하면 "Hello", "World!"로 두개의 문자열이 입력된 것으로 인식한다.

 

#include <stdio.h>

int main(void)
{
    char str[50] = "Hello World!";
    printf("String: %s\n", str);

    str[5]='\0';
    printf("String: %s\n", str);

    str[3]='\0';
    printf("String: %s\n", str);
    return 0;
}
/* output :
String: Hello World!
String: Hello
String: Hel
*/

문자열 중간중간 널문자를 삽입되면 문자열 끝이 변경되어 변경된 끝을 기준으로 문자열이 출력된다.

 

'Language > C, C++' 카테고리의 다른 글

[C] 포인터와 배열  (0) 2020.12.17
[C] 포인터 변수  (0) 2020.12.16
[C] 1차원 배열(1)  (0) 2020.12.12
[C] 재귀함수  (0) 2020.12.10
[C] register 변수  (0) 2020.12.10

+ Recent posts