[ 목차 ]
1. C프로그램 구성
2. 데이터형 / 변수 / 상수
3. 입출력
4. 연산자
5. 제어문
6. 1차원 배열
7. 다차원 배열
8. 함수
9. 포인터의 이해
10. 문자열
11. 메모리 동적 할당
12. 구조체
10. 문자열
10.1. 문자 상수 / 문자열 상수
문 자 | 문자열 | |
형태 | 한 글자 | 두 글자 이상 |
표기방법 | 작은 따옴표 (‘’) | 큰 따옴표 (“”) |
사용 예 | 'A', 't', '\n' | "apple", "banana" |
처리방법 | 정수로 처리된다. | 주소로 처리된다. |
특징 | 아스키코드와 대응된다. | 문자열 끝에 널 문자('\0')가 추가된다. 때문에 문자열의 길이보다 항상 1이 길다. |
* 문자열은 문자열상수가 저장된 시작주소로 처리 한다. 때문에 각기 다른 문자열 길이의 끝을 알 수 있도록 문자열 끝에는 문자열의 끝을 의미하는 널 문자(’\0‘)가 들어있다. 때문에 문자열의 길이는 실제 문자열의 길이보다 항상 1byte가 길다.
* 문자열 변환문자는 %s다. 입력 시 %s는 주소가 가리키는 메모리로부터 차례대로 한 글자씩 저장한 후 끝에 널 문자('\0')를 추가한다. 출력 시 %는 주소로부터 널 문자 이전까지 출력된다.
10.2. 문자열 처리 방법
- 배열을 이용한 문자열 처리
: 문자열은 문자열의 끝을 의미하는 널 문자가 있기 때문에 항상 문자열의 길이 보다 1byte크게 배열의 크기를 설정해야 한다. 또한, 한글은 1음절이 2byte기 때문에 음절의 두 배 + 1에 해당하는 크기로 설정해야 한다.
- 포인터를 이용한 문자열 처리
: 문자열은 문자열이 저장된 곳의 시작주소로 처리되기 때문에 char형 포인터는 문자열을 저장할 수 있다. 이 경우 포인터는 문자열의 주소를 저장하고 있는 것이다.
포인터에 문자열을 저장하면 문자열의 길이에 상관없이 문자열의 주소를 저장하는 4byte 포인터만 있으면 되기 때문에 메모리를 효율적으로 사용할 수 있다. 그러나 문자열의 수정은 불가능한 읽기 전용이 된다.
10.3. 문자열 입력함수
문자열을 입력받기 위해서는 반드시 메모리 공간이 할당 돼야 한다. 즉, 할당된 메모리의 크기만큼 문자열을 입력받을 수 있다. 배열에는 문자열을 입력받을 수 있지만 주소를 저장하는 4byte포인터에는 문자열을 입력받을 수 없다.
10.4. 문자열 함수
문자열 함수는 string.h에 정의되어 있으므로 문자열 함수를 사용하려면 이 헤더파일을 추가해야한다.
- strlen 함수 : 문자열의 주소로부터 널 문자 이전의 길이를 구해 리턴 하는 함수
- strcpy 함수 : 문자열을 복사하는 함수로 주소부터 널 문자까지 복사
- strcat 함수 : 첫 번째 문자열과 두 번째 문자열이 연결되어 첫 번째 문자열에 저장
- strcmp 함수 : 두 문자열이 완벽하게 일치하면0을, 앞 문자열이 크면 양수를(보통 1)를, 뒤 문자열이 크면 음수(보통 -1)을 리턴 하는 함수
- strrev 함수 : 널 문자 이전의 문자열을 역순으로 저장하는 함수
- strupr, strlwr 함수 : 소문자를 대문자로, 대문자를 소문자로 변환하는 함수
- strchr 함수 : 문자열에서 문자를 앞에서부터 검사하여 문자가 저장된 번지를 리턴 하는 함수
10.5. 데이터 변환 함수
데이터 변환 함수는 stdlib.h에 정의되어 있으므로 데이터 변환 함수를 사용하려면 이 헤더파일을 추가해야한다.
- atoi(Ascii to Integer) 함수 : 숫자 형태의 문자열을 정수로 변환하는 함수
- atof 함수 : 문자열을 부동 소수점으로 변환
- atol 함수 : 문자열을 long형 정수로 변환
- itoa(Integer to Ascii) 함수 : 정수를 문자열로 변환하는 함수
- ultoa 함수 : 부호 없는 정수를 문자열로 변환
11. 메모리 동적 할당
11.1. 메모리
프로그램이 실행되는 동안 저장되는 데이터는 RAM이라는 메모리 공간에 저장되며 RAM은 크게 다음과 같이 나눠진다.
메모리 영역 | 저장되는 데이터 |
Stack | 함수 내에서 선언된 지역 변수(매개변수) |
Heap | 동적으로 할당된 메모리 |
Data | 전역변수나 정적변수(static 변수) |
RAM | ||
High Address -> |
Stack Heap |
함수나 블록내에서만 메모리 할당 (지역변수, 매개변수) 프로그래머 할당/해제 |
Low Address -> |
Data |
프로그램 실행~종료될 때까지 메모리 할당 (전역변수, 정적변수(static변수)) |
여기서 Stack영역과 Heap영역은 정형화된 영역이 아니다. 즉, Stack영역이 많이 할당되면 Heap영역은 줄어들게 되며, Heap영역이 많이 할당되면 Stack영역은 줄어들게 되는 가변화된 공간이다.
Stack 영역과 Data영역은 시스템에 의해 할당되고 해제는 되는 영역이지만, Heap영역은 프로그래머에 의해 할당 및 해제가 이뤄지는 영역이다.
11.2. 정적 할당과 동적 할당
1. 정적 할당
1) Compile시 할당될 메모리 크기가 결정되어야 한다.
2) Stack영역과 Data영역에 할당되는 메모리는 모두 정적 할당이다.
2. 동적 할당
1) Runtime(실행)시 메모리가 할당되어야 한다.
2) 동적 할당된 메모리는 Heap영역에 할당된다. 때문에 Heap메모리를 동적 메모리라 함.
* 전역변수, 지역변수, 정적변수는 컴파일 시 할당될 메모리 크기를 결정할 수 있는 정적 할당
11.2.1. malloc 함수 / free 함수
동적으로 메모리를 할당하기 위해 malloc 함수를 해제하기 위해서는 free함수를 이용.
- 동적 메모리 할당
ex) void* malloc(size_t n);
: 인수의 크기만큼 메모리를 할당하고 할당된 메모리의 시작주소를 리턴.
: 리턴되는 주소는 void포인터 타입이기에 반드시 형 변환해서 사용해야 함.
- 동적 메모리 해제
ex) void free(void*)
: 주소가 가리키는 메모리를 해제한다.
- 헤더파일 : stdlib.h
: malloc함수와 free함수는 stdlib.h 헤더파일에 포함되어 있다.
** void 포인터(void*)는 모든 타입의 주소를 저장할 수 있는 포인터를 의미. void포인터는 간접접근을 할 수 없기 때문에 형 변환해서 주소가 가리키는 데이터로 접근해야 함.
※ 문자열 동적 할당은 문자열의 길이가 일정치 않은 데이터를 여러 개 저장할 때 사용한다. 문자열 동적 할당은 메모리를 동적 할당 한 후 할당된 주소를 포인터가 저장해야 하기 때문에 성능도 떨어지고 메모리를 잘못 할당할 수 있는 위험성도 있다. 그러나 일정치 않은 길이의 많은 데이터를 처리할 때 메모리를 효율적으로 사용할 수 있다는 장점이 있다.
12. 구조체
12.1. 구조체란,
구조체란 두 개 이상의 데이터형을 묶어서 새로운 데이터형을 정의하는 것을 말한다. 각각의 컬럼들은 독립된 의미를 갖는데 이를 모아 하나의 가치를 지니는 정보로 만드는 것이다. 즉, 각 항목을 서로 다른 변수에 저장하는 것이 아니라 필요한 정보를 그룹지어 하나의 변수에 저장할 수 있도록 데이터형을 정의하는 것이다.
12.2. 구조체 사용
1. 구조체 정의 struct 구조체명 { 멤버 1; 멤버 2; 멤버 n; }; 2. 구조체 선언 struct 구조체명 변수명; 3. 구조체 멤버 접근 변수명.멤버; 4. 구조체 초기화 struct 구조체명 구조체변수명 = {값1, 값2, 값3}; |
1) 구조체로 정의한 데이터형은 struct 키워드가 붙는다. 2) 구조체 정의 끝은 항상 세미콜론(;)으로 끝난다. 3) 구조체 정의 시 멤버변수 초기 값을 할당은 불가능하다. 구조체 멤버 초기화 방법은 배열과 같다 |
'C, C++' 카테고리의 다른 글
[C언어] C언어 기초 정리 #4 (함수와 포인터) (0) | 2025.03.18 |
---|---|
[C언어] C언어 기초 정리 #3 (제어문과 배열) (0) | 2025.03.17 |
[C언어] C언어 기초 정리 #2 (입출력과 연산자) (0) | 2025.03.16 |
[C언어] C언어 기초 정리 #1 (C 프로그램 구성 / 데이터형, 변수, 상수) (1) | 2025.03.16 |
[자료구조]중간값 찾기 (0) | 2022.07.14 |