자료형 배열이름[크기];
자료형 배열이름[크기] = {값1, 값2, 값3};
- 이 방법은 이미 선언된 배열에는 사용할 수 없다.
- 이 방법에서 크기를 생략할 수 있고, 크기는 자동으로 인자 수만큼 할당된다.
int numArr1[2] = {1, 2};
접근을 하려면 배열 뒤에 [인덱스]를 사용한다.
numArr[0]; // 0번 인덱스에 접근
배열의 인덱스는 0부터 시작
자료형 배열이름[크기] = {0,};
int numArr[10] = {0, }; // 배열의 요소를 모두 0으로 초기화
배열[인덱스] = 값;
int numArr[10];
numArr[0] = 11;
numArr[4] = 22;
배열의 범위를 벗어난 인덱스에 접근하면 쓰레기 값이 출력되며, 이는 배열이 아닌 다른 메모리 공간에 접근한 것이다.
int numArr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 크기 10인 int형 배열 선언 및 초기화
printf("%d", sizeof(numArr)); // 40 출력, 4바이트인 int형 요소가 10개이므로 40이 됨
printf("%d", sizeof(numArr) / sizeof(int)); // 10 출력, 전체 공간을 요소 크기로 나눠준다.
배열은 첫 번째 요소의 주솟값만 담고 있다.
int numArr[3] = {1, 2, 3};
int *numPtr = numArr; // 포인터에 int형 배열 할당
printf("%d", *numPtr); // 1 출력, 배열의 주소가 들어있는 포인터를 역참조하면 배열의 첫 번째 요소에 접근
printf("%d", *numArr); // 1 출력, 배열 자체를 역참조해도 마찬가지
printf("%d", numPtr[2]); // 3 출력, 배열의 주소가 들어있는 포인터는 인덱스로 접근이 가능하다.
printf("%d", sizeof(numArr)); // 12 출력, sizeof로 배열의 크기를 구하면 배열이 메모리에 차지하는 공간이 출력
printf("%d", sizeof(numPtr)); // sizeof로 배열의 주소가 들어있는 포인터의 크기를 구하면 포인터의 크기가 출력됨
단, 자료형이 같고, 1차원 배열이라면 단일 포인터여야 한다.
가로 * 세로 형태로 이루어진 배열, 평면 구조
자료형 배열이름[세로크기][가로크기];
자료형 배열이름[세로크기][가로크기] = {{값1, 값2, 값3}, {값4, 값5, 값6}};
int numArr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
printf("%d", numArr[0][1]); // 2 출력
int numArr[3][4] = {0, };
int numArr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
printf("%d", sizeof(numArr)); // 48 출력, 4바이트가 12개이므로 48
int col = sizeof(numArr[0]) / sizeof(int); // 4 출력, 가로 한줄의 크기를 요소의 크기로 나눠주면 가로 크기
int row = sizeof(numArr) / sizeof(numArr[0]); // 3 출력, 배열이 차지하는 전체 공간을 가로 한 줄의 크기로 나눠주면 세로 크기
자료형 (*포인터이름)[가로크기];
int (*numPtr)[4];
괄호의 유무에 따른 차이
- int (*numPtr)[4] : 배열을 가리키는 배열 포인터
- int *numPtr[4] : 포인터를 여러 개 담는 포인터 배열
이차원 배열을 포인터에 할당
int numArr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int (*numPtr)[4] = numArr;
printf("%p", *numPtr); // 세로 첫 번째 주소 출력
printf("%p", *numArr); // 세로 첫 번째 주소 출력
printf("%d", numPtr[2][1]); // 10 출력
printf("%d", sizeof(numArr)); // 48 출력
printf("%d", sizeof(numPtr)); // 포인터의 크기 출력
높이 * 가로 * 세로 형태
자료형 배열이름[높이][세로크기][가로크기];
int num[2][3][4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};
자료형 *포인터이름 = malloc(sizeof(자료형) * 크기);
int *numPtr = malloc(sizeof(int) * 10); // int 10개 크기만큼 동적 메모리 할당
numPtr[0] = 10; // 배열처럼 인덱스로 접근 가능
free(numPtr); // 메모리 해제
자료형 **포인터이름 = malloc(sizeof(자료형 *)* 세로크기);
- 반복문으로 포인터[i] = malloc(sizeof(자료형) * 가로크기);와 같이 가로 공간 메모리 할당
- 반복문으로 free(포인터[i]); 와 같이 가로 공간 메모리 해제
- free(포인터);와 같이 세로 공간 메모리 해제
int **m = malloc(sizeof(int *)*3); // 이중 포인터에 (int 포인터 크기 * 세로 크기)만큼 동적 메모리 할당, 배열의 세로
for (int i = 0; i < 3; i++) // 세로 크기만큼 반복
{
m[i] = malloc(sizeof(int) * 4); // (int 크기 * 가로 크기)만큼 동적 메모리 할당, 배열의 가로
}
m[0][0] = 1;
for (int i = 0; i < 3; i++) // 세로 크기만큼 반복
{
free(m[i]); // 2차원 배열의 가로 공간 메모리 해제
}
free(m); // 2차원 배열의 세로 공간 메모리 해제
문자열은 따로 자료형이 없다.
char *변수이름 = "문자열";
char *s1 = "Hello"; // 포인터에 문자열 "Hello"의 주소 저장
printf("%s", s1);
문자열의 마지막에 항상 NULL 문자가 붙는다.
문자열의 끝을 나타내며, printf는 문자열을 출력할때 NULL에서 출력을 끝낸다.
char *s1 = "Hi";
printf("%c", s1[1]); // i 출력, 1번 인덱스 출력
char 배열이름[크기] = "문자열";
char s1[10] = "Hi"; // 크기가 10인 char형 배열 선언하고 문자열 할당
printf("%s", s1);
배열에 문자열과 NULL을 저장하고 남은 공간은 보통 NULL로 채워짐
선언과 동시에 문자열로 초기화해야함
문자열을 배열로 선언할 때 반드시 NULL 값을 생각해서 크기를 정할 것
인덱스를 이용해서 문자에 접근이 가능하다.
scanf("%s", 배열);
- 성공하면 가져온 갑의 개수를 반환, 실패하면 EOF(-1) 반환
char s1[10];
scanf("%s", s1); // 배열은 scanf에서 &를 붙이지 않는다. 배열이 주소를 담고있기 때문
scanf("%[^\n]s", s1) // 공백까지 포함하여 문자열 입력받음
char *s1 = malloc(sizeof(char) * 10); // char 10개 크기만큼 동적 메모리 할당
scanf("%s", s1); // 표준 입력을 받아서 메모리가 할당된 문자열 포인터에 저장
free(s1);
scanf("%s%s...", 배열1, 배열2, ...);
scanf("%s%s...", 포인터1, 포인터2, ...);
scanf("%s %s", s1, s2); // 공백으로 구분된 문자열 두 개 입력받음
strlen 함수 사용, string.h에 선언
strlen(문자열포인터 or 문자배열);
- 문자열의 길이를 반환
char *s1 = "Hi";
printf("%d", strlen(s1)); // 2 출력
strlen은 순수한 문자열의 길이만 구해서, NULL은 포함하지 않는다.
strcmp 함수 사용, string.h에 선언
strcmp(문자열1, 문자열2);
- 문자열 비교 결과를 반환
char s1[10] = "Hi";
char *s2 = "Hi";
int result = strcmp(s1, s2)
printf("%d", result); // 0 출력, 두 문자열이 같으면 0 반환
반환값
- -1 : ASCII 코드 기준으로 문자열2가 클 때
- 0 : ASCII 코드 기준으로 두 문자열이 같을 때
- 1 : ASCII 코드 기준으로 문자열1이 클 때
그냥 사전 순으로 뒤에 있는 것이 크고 앞에 있는 것이 작음
리눅스에서는 반환값이 ASCII 코드값의 차이를 반환, 즉 음수, 0, 양수로 판별하면 됨