(C언어) 배열과 함수, 배열과 포인터

일반적인 매개 변수

 

#include <stdio.h>
int square(int a);

int main(void)
{
    int p = 16;
    int res = square(p);

    return 0;
}
int square(int a)
{
    return a * a;
}

1.JPG
2.JPG

일반적인 매개 변수는 함수가 실행되면 기억 장소가 할당된다.

위 예에서도 square 함수가 실행되면 a에 실제로 기억 장소가 할당되고 p값은 16이 저장된다.


배열 매개 변수

 

변수를 함수로 전달하듯이 배열도 함수로 전달할 수 있다.

다만 동작 방식이 조금 다르다.

#include <stdio.h>
int square(int a[]);

int main(void)
{
    int p[3] = { 1,2,3 };
    square(p);

    return 0;
}
int square(int a[])
{
    for (int i = 0; i < 3; i++)
        a[i] = a[i] * a[i];
}

3.JPG

배열 매개 변수 a는 공간을 할당 받는 대신 main 함수에서 생성된 배열 p를 가리키는 포인터가 된다.

4.JPG

그래서 함수 내에서 배열을 조작하게 되면 원본이 변경된다.

배열을 함수로 전달하면 원본 배열이 전달되는 것과 마찬가지다.

배열 요소를 전달하는 경우에는 개별 변수가 전달되는 것과 마찬가지이므로 복사본이 전달된다.

int square(const int a[])

함수 내부에서 원본 배열이 변경되기를 바라지 않는 경우 매개 변수 앞에 const를 붙여 변경이 불가능하게 만들면 된다.


포인터와 배열

 

배열 이름은 배열이 시작되는 주소와 같다.

#include <stdio.h>

int main(void)
{
    int p[3] = { 1,2,3 };
    printf("p[0]:%u\n", &p[0]);
    printf("p[1]:%u\n", &p[1]);
    printf("p[2]%u\n", &p[2]);

    printf("p:%u\n", p);

    return 0;
}

5.JPG

배열 각 요소의 주소를 출력하면 int값의 크기에 맞게 4씩 증가하는 것을 알 수 있다.

또한 첫 번째 요소가 가리키는 주소와 배열 이름이 가리키는 주소가 일치한다. 이는 배열의 이름이 배열이 시작되는 주소를 가리키는 포인터라는 의미이다.

#include <stdio.h>

int main(void)
{
    int a[3] = { 1,2,3 };
    int* p;
    p = a
    printf("%d\n", a[0]);
    printf("%d\n", p[0]);    //포인터를 배열 이름으로
    printf("%d\n", *(a+1));    //배열 이름을 포인터로
    printf("%d\n", *(p+1));

    return 0;
}

6.JPG

배열 이름이 포인터이므로 배열 이름을 포인터에 사용할 수 있다.

포인터를 배열 이름처럼 사용할 수도 있다.

배열 a를 가리키는 포인터 p를 선언하면 배열 이름으로 a를 사용하나 p를 사용하나 같은 값을 출력한다.

arr = (int *)malloc(sizeof(int) * size);    //size는 배열의 크기

배열과 포인터의 관계를 이용하면 포인터에 메모리를 할당해 배열처럼 활용할 수 있다.