[TIL] 240430 - 함수, 배열, 포인터

jini·2024년 4월 29일
0

TIL

목록 보기
3/48

함수


표준 함수 : 언어에서 기본적인 라이브러리로 제공해주는 함수

사용자 정의 함수 : 사용자가 자신이 원하는 기능을 직접 만드는 함수

int func(x, y)
{
	함수의 내용
}
  • return type : 함수가 반환하는 데이터의 타입
  • 함수 이름 : 함수를 호출하기 위한 이름
  • parameters : 함수 호출 시에 전달되는 인수의 값을 저장할 변수
  • 함수의 내용 : 함수의 기능을 수행하는 명령문

📋 void 타입

함수 내부에서 동작만 하고 결과값을 반환하지 않는 함수

#include <stdio.h>

void func()
{
	printf("void type\n");
}



변수의 범위


📋 지역변수

블록 내부공간에 선언되는 변수이며, 블록을 벗어나게 되면 사라짐

함수의 매개변수도 스택 메모리에 할당되는 지역변수


📋 전역변수

블록 외부공간에 선언되는 변수이며, 어느 지역에서든 참조 가능

프로그램이 시작할 때 메모리 상에 올라가서 프로그램이 종료될 때 소멸

#include <stdio.h>;

int global;

void Add(int x, int y)
{
	global = x + y;
}

int main()
{
	int x = 10;
	int y = 20;

	Add(x, y);
	printf("%d\n", global);
	
	return 0;
}

📋 static 변수

블록 내부공간에 선언되지만 블록을 벗어나도 메모리 상에 고정되어 소멸하지 않음

#include <stdio.h>;

void func()
{
	static int result = 0;
    result++;
    printf("%d\n", result);
}

int main()
{
	for(int i = 0; i < 5; i++){
    	func();
    }
}



배열


📋 배열의 구조

배열은 같은 속성을 가진 것들을 나열해 놓은 것
배열의 첫 번째 인덱스틑 0부터 시작

int a[100];
  • 배열의 타입 : 배열 요소들의 타입
  • 배열 이름 : 각 배열 요소에 접근하기 위한 배열 이름
  • 배열 길이 : 변수의 개수

📋 배열의 초기화

#include <stdio.h>

int main()
{
	int sum = 0;
	int array[5] = {1, 2, 3, 4};
	
	sum = array[0] + array[1] + array[2] + array[3];
	printf("%d\n", sum);
	return 0;
}

배열의 길이 생략 → 초기값의 개수를 보고 컴파일러는 배열의 길이를 계산


📋 배열의 복사

같은 타입의 배열끼리 복사 가능하지만 변수 복사하듯이 복사하면 에러 발생

int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5];
arr2 = arr1;

⚠️ error C2106 : 배열은 상수이기 때문에 대입 연산자를 통해 값을 넘겨 받을 수 없음

→ 배열은 요소끼리 복사해야 함

#include <stdio.h>

int ain()
{
	int arr1[4] = {1, 2, 3, 4};
	int arr2[4];
	
	for(i = 0; i < 4; i++){
		arr2[i] = arr1[i];
	}
	
	for(i = 0; i < 4; i++){
		printf("%d\n", arr2[i]);
	}
	
	return 0;
}

📋 문자열 변수

문자열은 모두 상수이지만 문자열에 이름을 붙여주면 변수로 사용 가능

char str[12] = "Hello World";

문자열은 총 11개인데 12개인 이유는 문자열의 끝에 null 문자가 추가되기 때문

null 문자

문자열 끝에는 null 문자가 반드시 추가

char str[100] = "Beautiful";

문자수는 9개이고, 배열의 개수는 100개 이므로 91개의 공간이 비기 때문에 쓰레기 값으로 채워짐

컴퓨터는 문자와 쓰레기 값을 구분할 수 없기 때문에 컴퓨터가 문자열의 끝을 인식하기 위해 null을 표시
→ “Beautiful”의 공간은 9개가 아닌, null을 포함한 10개



포인터


메모리는 주소를 통해 메모리에 접근하여 값을 읽고 쓸 수 있음

포인터는 포인터 변수의 줄임말로 메모리의 주소값을 저장하고 있는 변수( = 해당 메모리를 가리킴)


📋 포인터 사용방법

포인터 변수 선언 시 일반 변수명 앞에 * 기호를 붙여줌
→ 주소값만 저장하다는 의미

char *pA;
int *pB;

&기호를 통해 주소값을 얻어오기

int b = 100;
int *pB = &b;

사용 예시

#include <stdio.h>

int main(void)
{
	int b = 100;
    int *pB = &b;
    
    printf("b = %d\n", b);     // 100
    printf("&b = %d\n", &b);   // b의 주소
    printf("*pB = %d\n", *pB); // 100
    printf("pB = %d\n", pB);   // b의 주소
	
	return 0;
}

📋 포인터와 배열

배열의 이름은 해당 배열의 첫 번째 요소의 주소값을 가짐
= 첫 번째 요소의 주소값을 가리키는 포인터
arr == &arr[0]

#include <stdio.h>

int main()
{
	int arr[] = {1, 2, 3, 4, 5};
	
	for(int i = 0; i < 5; i++){
		printf("%d\n", arr[i]);
		printf("%p\n", &arr[i]);
	}
	return 0;
}

⚠️ 배열의 이름은 주소값을 갖는 포인터이지만 상수이므로 주소값을 변경할 수 없음


📋 함수와 포인터

기본적인 함수의 인자 전달 형태는 복사이지만, 배열형의 인자는 포인터형으로 받음
→ 배열을 전달인자로 사용하면 여러 개의 값을 넘길 수 있음

#include <stdio.h>

void func(int *pArr){
	for(int i = 0; i < 5; i++){
		printf("arr[%d] : %d\n", i, *(pArr + i));
	}
}

int main() 
{
	int arr[] = {1, 2, 3, 4, 5};
	func(arr);
	
	return 0;
}

함수의 전달인자 arr은 주소값을 넘기고 있으며, 주소값을 넘겨 받기 위해서는 포인터 형태로 받아야 하기 때문에 함수 인수의 형태가 int *pArr임을 볼 수 있음

0개의 댓글