필수실습문제)
11-01) 중대한 두 가지 오류
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char szBuffer[12] = {"HelloWorld"};
char *pszData = NULL;
pszData = (char*)malloc( sizeof(char) * 12 );
pszData = szBuffer;
puts(pszData);
return 0;
}
이 예제를 작성하여 실행하면 실행결과가 잘 출력됨을 확인할 수 있습니다. 즉, 외형적으로나 결과적으로나 아무런 결함이 없어 보입니다.
그러나 다음 코드는 두 가지 심각한 결함이 있습니다. 그 두 가지 결함이 무엇인지 답하고 문제가 없는 코드가 될 수 있도록 수정합니다.
Q )
pszData 에는 malloc을 사용해 운영체제로부터 할당받은 12byte의 메모리 주소가 들어있었는데, pszData에 szBuffer의 주소를 대입해
pszData에 저장되어 있던 12byte의 동적 메모리를 사용하지 못하게 되었다.
또한 그 동적 메모리를 free()를 해서 해제를 해주어야 하는데, 이를 해제하지도 않고있다.
(물론 이 상황에서 해제를 하면 동적할당 받은 메모리가 아니라 stack의 메모리를 해제하려고 하기때문에 error가 날 것이다.)
pszData = szBuffer 부분을 memcpy(pszData, szBuffer, (sizeof(char) * 12)); 로 변경하면 된다.
11-02) 문자열과 상대주소 계산
#include <stdio.h>
#include <string.h>
int main(void) {
char szBuffer[32] = {"You are a girl."};
char *pszData = szBuffer + 4;
printf("%c\n", szBuffer[0]);
printf("%c\n", pszData[0]);
printf("%c\n", pszData[6]);
printf("%s\n", szBuffer + 4);
printf("%s\n", pszData);
printf("%s\n", pszData + 4);
return 0;
}
다음 코드에서 배열 szBuffer의 메모리 구조를 그림으로 표현한 후, 예제의 실행결과를 작성합니다. 특히, 세 번째와 여섯 번째 printf() 함수의 출력 결과에 대해서는 왜 그런 결과가 출력되었는지 이유를 기술합니다.
Q )
szBuffer의 메모리 주소를 0x0018FF20 이라고 가정하자. 그러면 You are a girl. 은 앞에서부터 0x0018FF20, 21, 22, 23 ... 순서일 것이다.
pszData 에 szBuffer + 4를 대입 했는데 szBuffer는 char형이기 때문에 pszData에 저장되는 메모리 주소는 0x0018FF24가 될 것이다.
순서대로 출력 결과를 살펴보자면
szBuffer[0] : Y
pszData[0] : a
pszData[6] : g
위 경우에는 형식 문자열을 %c를 사용하기 때문에 인자로 char 형 데이터를 입력받는다. 그렇기에 배열[] 형태의 데이터를 입력해 주었다.
szBuffer[0]의 경우 문자열의 첫 번째 문자인 Y가 출력되고
pszData[0]의 경우 0x0018FF24에 저장된 문자 a가 출력되고
pszData[6]의 경우 0x0018FF24에서 6 더한 0x0018FF30 에 저장된 문자 g가 출력된다.
szBuffer + 4 : are a girl.
pszData : are a girl.
pszData + 4 : a girl.
위 경우에는 형식 문자열을 %s를 사용하기 때문에 인자로 char *형 데이터를 입력받는다. 그렇기에 배열의 이름을 입력해 주었다.
szBuffer + 4의 경우 szBuffer의 기준주소인 0x0018FF20 + 4인 0x0018FF24에 저장된 a 부터 '\0'을 만날 때 까지 출력하므로 are a girl.을 출력한다.
pszData의 경우 0x0018FF24에 저장된 문자 a 부터 '\0'을 만날 때 까지 출력하므로 are a girl.을 출력하고
pszData + 4의 경우 pszData의 기준주소인 0x0018FF24 + 4인 0x0018FF28에 저장된 a 부터 '\0'을 만날 대 까지 a girl.을 출력한다.
연습문제)
1) int형 변수 nData가 선언되었다고 가정한다면, 소스코드에 기술된 'nData'와 '&nData'의 차이점이 무엇인지
기술하세요.
Q )
변수는 메모리에서 특정 영역에 할당된 메모리 공간을 의미한다.
이러한 변수는 3가지 요소를 가지는데, 이 요소는 이름, 주소, 내용이다.
nData만 기술하게 되면 이는 변수의 '내용'이 되고,
&nData라고 기술하게 되면 이는 변수의 '주소'를 뜻하게된다.
2) 매개변수로 char*형 자료를 받아서 문자열의 길이를 계산해 반환하는 함수를 작성하세요.
함수의 이름은 GetLength()로 합니다.
Q )
3) 다음 코드의 논리적 오류 두 가지는 무엇이고 어떻게 수정해야 하는지 기술하세요.
- 필수실습문제 1번과 동일하므로 생략
4) 인터넷에서 strrev() 함수의 사용방법에 대해 찾아보고 이 함수와 동일한 기능을 수행할 수 있는 MyStrrev() 함수를
작성 하세요.
Q )
strrev() 함수 원형
char* strrev(char* string);
문자열의 기준주소 (char*)를 입력받아 문자열을 뒤집고 그 문자열의 주소를 반환하는 함수.
5) 사용자로부터 입력받은 첫 번째 문자열을 동적 할당된 메모리에 저장한 후 화면에 출력하고,
두 번째로 입력받은 문자열을 첫 번째로 동적 할당된 메모리에 덧붙여 출력하는 프로그램을 작성합니다.
이때, 메모리가 부족해서 문제가 발생하지 않도록 메모리의 크기를 조정합니다.
기존에 할당받은 메모리의 크기를 늘려도 좋고 다시 할당받아도 좋습니다.
혹은 두 경우를 모두 구현하는 것도 좋습니다.
Q )
6) 정수를 입력받고, 그 개수만큼 char*를 여러 개 저장할 수 있는 메모리를 동적 할당합니다.
그리고 입력할 문자열의 최대 길이를 입력받고, 최대 길이의 문자열을 저장할 수 있는 크기의 메모리를
동적 할당하여 입력받는 문자열을 저장한 후 출력하는 프로그램을 작성합니다.
Q )
실행 결과
- 출처 : 독하게 시작하는 C 프로그래밍 (최호성, 루비 페이퍼)
'Programming > C language' 카테고리의 다른 글
Chapter 12. 함수 응용 (문제풀이) (0) | 2017.06.30 |
---|---|
Chapter 12. 함수 응용 (내용 요약) (0) | 2017.06.30 |
chapter 11. 메모리와 포인터 (내용요약 - 3) (0) | 2017.06.29 |
chapter 11. 메모리와 포인터 (내용요약 - 2) (0) | 2017.06.28 |
Chapter 11. 메모리와 포인터 (내용 요약 - 1) (0) | 2017.06.28 |