문자열
문자열은 " "(큰따옴표)로 묶으며 char 포인터나 배열에 저장하여 사용합니다.
char *s1 = "Hello, world!"; // char 포인터에 문자열의 메모리 주소를 저장
char s2[20] = "Hello, world!"; // char 배열에 문자열 저장
char s3[] = "Hello, world!"; // char 배열에 문자열 저장(배열의 크기 생략)
문자열을 인덱스로 접근하면 문자를 출력할 수 있습니다.
// 문자열을 인덱스로 접근
printf("%c\n", s1[0]); // H
printf("%c\n", s2[4]); // o
이미 선언된 배열에는 문자열을 할당할 수 없습니다.
char s1[20];
s1 = "Hello, world"; // 컴파일 에러
문자열 포인터와 문자 배열의 요소 변경
문자열 포인터에 문자열 리터럴을 할당한 뒤에는 인덱스로 접근하여 문자(요소)를 변경할 수 없습니다(문자열 리터럴이 있는 메모리 주소는 읽기 전용). 하지만 문자 배열은 인덱스로 접근하여 문자를 변경할 수 있습니다(배열에 문자열이 복사됨).
char *s1 = "Hello"; // 문자열 포인터에 문자열 리터럴 할당(읽기 전용 메모리를 가리킴)
s1[0] = 'A'; // 실행 에러: 문자를 변경할 수 없음
char s2[10] = "Hello"; // 문자 배열에 문자열 리터럴 할당(배열에 문자열이 복사됨)
s1[0] = 'A'; // 문자를 변경할 수 있음
입력된 문자열을 배열 또는 포인터에 저장하기
입력된 문자열을 배열에 저장할 때는 scanf 함수를 사용하며 배열 앞에는 &를 붙이지 않습니다.
char s1[10]; // 크기가 10인 char형 배열을 선언
scanf("%s", s1); // 표준 입력을 받아서 배열 형태의 문자열에 저장
입력된 문자열을 포인터에 저장할 때도 포인터 앞에는 &를 붙이지 않습니다.
char *s1 = malloc(sizeof(char) * 10); // char 10개 크기만큼 동적 메모리 할당
scanf("%s", s1); // 표준 입력을 받아서 배열 형태의 문자열에 저장
free(s1); // 동적 메모리 해제
문자열과 서식 지정자
문자열은 서식 지정자 %s를 사용합니다.
char s1[20];
scanf("%s", s1); // %s로 문자열을 입력받음
printf("%s", s1); // %s로 문자열을 출력
scanf로 공백까지 포함하여 문자열을 입력받으려면 서식 지정자로 "%[^\n]s"를 사용합니다.
char s1[30];
scanf("%[^\n]s", s1); // 공백까지 포함하여 문자열 입력받기
문자열과 NULL
문자열은 문자열의 끝나는 지점을 알려주기 위해 마지막에 NULL(\0)이 붙습니다. 만약 배열이라면 NULL까지 들어가야 하므로 배열의 크기는 문자열의 길이보다 1이 더 커야 합니다.
char s1[6] = "Hello"; // 5글자 + NULL이므로 배열의 최소 크기는 6이상
다음은 문자열 함수의 매개변수, 반환값과 설명을 정리한 표입니다.
표 문자열 함수strlen(문자열포인터); strlen(문자배열); |
string.h | 문자열의 길이를 구합니다(NULL은 포함하지 않음). |
strcmp(문자열1, 문자열2); | string.h | 문자열1과 문자열2를 비교합니다(Windows).
리눅스와 OS X에서는 문자열1의 ASCII 코드값에서 문자열2의 ASCII 코드값을 뺀 결과를 반환합니다.
|
strcpy(대상문자열, 원본문자열); | string.h | 문자열을 복사합니다. |
strcat(최종문자열, 붙일문자열); | string.h | 문자열을 붙입니다. |
sprintf(배열, 서식, 값); sprintf(배열, 서식, 값1, 값2, ...); sprintf(문자열포인터, 서식, 값); sprintf(문자열포인터, 서식, 값1, 값2, ...); |
stdio.h | 서식을 지정하여 문자열을 생성합니다. |
strchr(문자열, 검색할문자); | string.h | 문자열 안에서 문자로 검색합니다. 문자를 찾았으면 해당 문자부터 NULL 바로 앞까지의 문자열이 나옵니다 (해당 문자의 포인터 반환). |
strrchr(문자열, 검색할문자); | string.h | 문자열의 뒤에서부터 문자로 검색합니다. 문자를 찾았으면 해당 문자부터 NULL 바로 앞까지의 문자열이 나옵니다(해당 문자의 포인터 반환). |
strstr(대상문자열, 검색할문자열); | string.h | 문자열 안에서 문자열로 검색합니다. 문자열을 찾았으면 해당 문자열부터 NULL 바로 앞까지의 문자열이 나옵니다(해당 문자열의 포인터 반환). |
strtok(대상문자열, 기준문자); | string.h | 문자를 기준으로 문자열을 자릅니다. 자른 문자열을 한 번에 얻을 수 없으므로 while로 계속 반복 사용해야 합니다. 그리고 문자열을 자른 부분은 NULL로 바뀝니다. |
atoi(문자열); | stdlib.h | 문자열을 정수로 변환합니다. |
atof(문자열); | stdlib.h | 문자열을 실수로 변환합니다. |
strtol(문자열, 끝포인터, 진법); | stdlib.h | 특정 진법으로 표기된 문자열을 정수로 변환 합니다. 정수 여러 개가 들어있는 문자열을 변환할 수 있습니다. |
strtof(문자열, 끝포인터); | stdlib.h | 문자열을 실수로 변환합니다. 실수 여러 개가 들어있는 문자열을 변환할 수 있습니다. |
sprintf(문자열,"%d", 정수); sprintf(문자열,"%x", 정수); sprintf(문자열,"%X", 정수); |
stdio.h | 정수를 문자열로 변환합니다.
|
sprintf(문자열,"%f", 실수); | stdio.h | 실수를 문자열로 변환합니다. |
typedef를 사용하면 구조체를 포함하여 모든 자료형의 별칭을 정의할 수 있습니다.
typedef 자료형 별칭; // 자료형의 별칭 정의
typedef 자료형* 별칭; // 자료형 포인터의 별칭 정의
구조체
구조체는 struct 키워드로 정의하며 관련 정보를 하나의 의미로 묶을 때 사용합니다.
// 구조체 정의하기
struct 구조체이름 {
자료형 멤버이름;
};
// 구조체 변수 선언하기
struct 구조체이름 변수이름;
// 구조체 변수를 선언하는 동시에 값을 초기화
struct 구조체이름 변수이름 = { .멤버이름1 = 값1, .멤버이름2 = 값2 };
struct 구조체이름 변수이름 = { 값1, 값2 };
// 구조체를 정의하는 동시에 변수 선언하기
struct 구조체이름 {
자료형 멤버이름;
} 변수;
// 구조체를 정의하면서 구조체 별칭 정의하기
typedef struct 구조체이름 {
자료형 멤버이름;
} 구조체별칭;
// 익명 구조체 정의하기
typedef struct {
자료형 멤버이름;
} 구조체별칭;
// 구조체 별칭으로 변수 선언하기
구조체별칭 변수이름;
구조체 멤버에 접근할 때는 . (점)을 사용합니다.
struct 구조체이름 변수이름;
변수.멤버; // 구조체 멤버의 값을 가져옴
변수.멤버 = 값; // 구조체 멤버에 값을 저장
malloc 함수로 구조체 포인터에 메모리를 할당할 수 있으며 이때는 멤버에 접근할 때 -> (화살표 연산자)를 사용합니다.
// 구조체 포인터에 동적 메모리 할당
struct 구조체이름 *포인터이름 = malloc(sizeof(struct 구조체이름));
// 구조체 별칭으로 포인터를 선언하고 동적 메모리 할당
구조체별칭 *포인터이름 = malloc(sizeof(구조체별칭));
포인터->멤버; // 구조체 포인터 멤버의 값을 가져옴
포인터->멤버 = 값; // 구조체 포인터 멤버에 값을 저장
free(포인터); // 구조체 메모리 해제
구조체 포인터에는 & (주소 연산자)로 구조체 변수의 메모리 주소를 구해서 할당할 수 있습니다.
구조체포인터 = &구조체변수;
구조체 배열
구조체 변수를 선언하려면 [ ] (대괄호)에 크기를 지정합니다. 구조체 배열의 멤버에 접근하려면 [ ]에 인덱스를 지정한 뒤 .으로 접근합니다.
// 구조체 배열 선언하기
struct 구조체이름 변수이름[크기];
// 구조체 배열을 선언하는 동시에 값을 초기화
struct 구조체이름 변수이름[크기] = { { .멤버이름1 = 값1, .멤버이름2 = 값2 },
{ .멤버이름1 = 값3, .멤버이름2 = 값4 } };
struct 구조체이름 변수이름[크기] = { { 값1, 값2 }, { 값3, 값4 } };
배열[인덱스].멤버; // 구조체 배열에서 요소의 멤버 값을 가져옴
배열[인덱스].멤버 = 값; // 구조체 배열에서 요소의 멤버에 값을 저장
구조체 포인터 배열
구조체 포인터 배열을 선언하려면 포인터 변수 이름 뒤에 [ ]를 붙인 뒤 크기를 지정합니다. 이때 배열의 요소에는 메모리를 할당해야 하며 멤버에 접근할 때는 [ ]에 인덱스를 지정한 뒤 ->로 접근합니다.
// 구조체 포인터 배열 선언하기
struct 구조체이름 *포인터이름[크기];
// 구조체 포인터 배열에 메모리 할당하기
for (int i = 0; i < 크기; i++) // 배열 크기만큼 반복
{
배열[i] = malloc(sizeof(struct 구조체)); // 각 요소에 구조체 크기만큼 메모리 할당
}
배열[인덱스]->멤버; // 구조체 포인터 배열에서 요소의 멤버 값을 가져옴
배열[인덱스]->멤버 = 값; // 구조체 포인터 배열에서 요소의 멤버에 값을 저장
// 구조체 포인터 배열의 메모리 해제하기
for (int i = 0; i < 크기; i++) // 배열 크기만큼 반복
{
free(포인터[i]); // 각 요소의 동적 메모리 해제
}
열거형
열거형은 정수형 상수에 이름을 붙입니다. 열거형에 초깃값을 지정하지 않으면 0부터 시작합니다.
// 열거형 정의하기
enum 열거형이름 {
값1 = 초깃값,
값2,
값3,
};
// 값의 개수까지 포함된 열거형 정의하기
enum 열거형이름 {
값1 = 초깃값,
값2,
값3,
열거형Count // 값의 개수를 나타내는 항목
};
// 열거형 변수 선언하기
enum 열거형이름 변수이름;
변수 = 열거형값1; // 열거형 변수에 열거형 값 할당
// 열거형을 정의하면서 열거형 별칭 정의하기
typedef enum 열거형이름 {
값1 = 초깃값,
값2,
값3
} 열거형별칭;
// 열거형을 정의하면서 열거형 별칭 정의하기(값의 개수 포함)
typedef enum 열거형이름 {
값1 = 초깃값,
값2,
값3
열거형Count // 값의 개수를 나타내는 항목
} 열거형별칭;
// 열거형 별칭으로 변수 선언하기
열거형별칭 변수이름;
// 열거형을 switch에 활용하기
switch (열거형변수)
{
case 열거형값1:
코드1;
break;
case 열거형값2:
코드2;
break;
}
// 열거형을 for에 활용하기
for (열거형이름 i = 열거형값1; i < 열거형Count; i++) // 초깃값은 열거형값1,
{ // 열거형Count보다 작을 때까지 반복
코드;
}
8일차 학습내용 C언어 파일 전역변수 지역변수 (0) | 2024.05.21 |
---|---|
7일차 학습내용 C언어 함수 파일 (0) | 2024.05.20 |
5일차학습내용_C언어_중첩루프_포인터_배열 (0) | 2024.05.16 |
4일차 학습내용_c언어 swich, for ,while, dowhile, break,continue (0) | 2024.05.14 |
3일차 학습내용_c언어 if문 연산자 (0) | 2024.05.13 |