[1.1]
/*
2개의 double형 값(x, y)을 입력받고 두 값에 대한 사칙연산(+, -, *, /) 결과값을 출력해 보라.
실행 결과는 다음과 같다. y의 값은 0이 아니라고 가정하라
*/
#include <stdio.h>
int main(void)
{
double num1, num2;
printf("두개의 실수 입력:");
scanf("%lf %lf", &num1, &num2);
printf("%lf+%lf=%lf\n", num1, num2, num1 + num2);
printf("%lf-%lf=%lf\n", num1, num2, num1 - num2);
printf("%lf*%lf=%lf\n", num1, num2, num1 * num2);
printf("%lf/%lf=%lf\n", num1, num2, num1 / num2);
return 0;
}
[1.2]
/*
2개의 int형 값(x, y)을 scanf 함수를 사용하여 읽어 들이도록 한다.이때 x는 y보다 작다고 가정한다.
그리고 실행화면을 참고하여 x와 y 사이의 값들에 대한 제곱값과 나누기 3을 한값을 각각 출력해 보도록 합시다.
단, 실행화면과 같이 각 출력값들에 대해 적절한 크기의 필드를 지정하고 오른쪽 정렬로 출력하도록 한다.
나누기 3을 한 값의 결과는 실수로 처리될 수 있어야하며 소수점 이하 첫 번째 자리까지만 출력하도록 한다.
*/
#include <stdio.h>
int main(void)
{
int x, y;
printf("두개의 정수 입력:(단, 첫번째 정수가 두번째 정수보다 작다)");
scanf("%d %d", &x, &y);
while (x >= y)
{
printf("첫번째 정수가 두번째 정수보다 작아야합니다\n");
printf("다시 입력:");
scanf("%d %d", &x, &y);
}
for (int i = x; i <= y; i++)
{
printf("%d\t%d\t%.1f\n", i, i*i, (double)i / 3); //소수점 첫번째 자리까지 .1
}
return 0;
}
[1.3]
/*
10개의 원소를 가지는 int형 배열을 선언하고 각각 자신의 index의 제곱값으로 채운다.
그리고 화면 출력을 통해 제대로 채워졌는지 확인해 보도록 한다.
이 문제는 1차원 배열의 사용 방법을 연습하기 위한 문제이다
*/
#include <stdio.h>
int main(void)
{
int arr[10]; //배열
for (int i = 0; i < 10; i++)
{
arr[i] = i*i; //각각 자신의 index의 제곱값
}
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
[1.4]
/*
5행 5열의 원소를 가지는 char형 배열을 선언하고 실행 결과와 같이 마름모 모양으로 '*'문자를 채워보도록 한다
마름모 이외의 영역은 공백 문자로 채우면 된다
*/
#include <stdio.h>
int main(void)
{
for (int i = 0; i < 3; i++) //위 삼각형
{
int j = 2;
while (i < j)
{
printf(" "); //공백문자
j--;
}
for (int k = 0; k <= i*2; k++) //*문자
printf("*");
printf("\n");
}
for (int i = 1; i >=0; i--) //아래 삼각형
{
int j = 2;
while (i < j)
{
printf(" "); //공백문자
j--;
}
for (int k = 0; k <= i*2; k++) //*문자
printf("*");
printf("\n");
}
return 0;
}
[1.5]
/*
2개의 int형 변수를 선언하고 각각 1, 2로 초기화한다.
그리고 하나의 int형 포인터 변수를 선언하고 포인터 변수만을 사용하여 앞서 선언한 2개의 변수를 번갈아 가리키면서 각 변수의 값을 100과 200으로 변경한다.
그리고 마찬가지로 포인터 변수만을 사용하여 각 변수의 값을 출력한다
*/
#include <stdio.h>
int main(void)
{
int num1 = 1, num2 = 2; //각각 1, 2로 초기화
int *ptr; //하나의 포인터 변수 선언
printf("기존의 num1의 값은:%d\n", num1);
ptr = &num1;
*ptr = 100;
printf("바뀐 num1의 값은:%d\n", *ptr);
printf("기존의 num2의 값은:%d\n", num2);
ptr = &num2;
*ptr = 200; //변경
printf("num2의 값은:%d\n", *ptr);
return 0;
}
[1.6]
/*
int형 포인터 변수 하나를 만들고 이를 통해 10개의 원소를 가진 int형 배열을 동적으로 할당해본다.
그리고 int형 포인터 변수를 추가로 하나 더 만들도록 한다.
이제 새롭게 만든 포인터 변수만을 사용하여 동적으로 할당한 배열의 각 원소의 값을 무작위 값으로 채우고,
역시 두 번째 포인터 변수를 사용하여 배열의 값들을 화면에 출력한다.
이문 제를 통해 메모리 동적할당에 대해 연습하고 포인터 변수만을 가지고 배열을 자유롭게 다룰 수 있는지 확인한다
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int *ptr = (int*)malloc(sizeof(int) * 10);
int *ptr2; //새로운 포인터 변수
srand((unsigned)time(NULL));
ptr2 = ptr;
for (int i = 0; i < 10; i++)
ptr2[i] = rand();
for (int i = 0; i < 10; i++)
printf("%d ", ptr2[i]);
printf("\n");
return 0;
}
[1.7]
/*
다음 프로그램의 출력 결과가 무엇인지 예상하고 왜 그런지 설명한다.
과연 예상한 대로 출력이 되는지 확인한다
*/
#include <stdio.h>
int main(void)
{
int ary[3][2] = { {1, 2}, {3, 4}, {5, 6} };
int(*pAry)[2] = ary;
printf("%d\n", **pAry);
printf("%d\n", *(*pAry + 1));
pAry++;
printf("%d\n", **pAry);
printf("%d\n", *(*pAry + 1));
pAry++;
printf("%d\n", **pAry);
printf("%d\n", *(*pAry + 1));
return 0;
}
[1.8]
/*
두 개의 문자열(char*)을 매개변수로 전달받아 두 번째 문자열을 첫 번째 문자열 뒤에 추가하는 함수를 작성한다.
함수명은 StrCat으로 한다.
다음 main 함수의 실행결과를 참고하도록 한다.
단, 첫번째 매개변수로 전달된 문자열의 버퍼(char 배열)는 두 번째 문자열까지 수용할만큼 충분한 크기를 확보하고 있다고 가정한다.
*/
#include <stdio.h>
#include <string.h>
void StrCat(char *str1, char *str2);
int main(void)
{
char str1[100] = "C++ ";
char *str2 = "Programming";
StrCat(str1, str2);
printf("str1:%s\n", str1);
return 0;
}
void StrCat(char *str1, char *str2)
{
int len = strlen(str1);
str1[len] = 0; //\n을 지워준다
memcpy(str1+len, str2, strlen(str2)); //주소값을 이용해 붙인다
}
[1.9]
/*
(예제 1.5)에서 x^y을 계산하는 power 함수를 구현하였다.
이번에는 이 함수를 재귀 함수(recursive function)로 구현한다.
재귀 함수는 특정함수 내에서 또 다시 그 함수를 호출하는 함수를 의미한다.
다음 예는 재귀함수를 사용하여 특정 문자열을 지정한 횟수만큼 출력하는 프로그램이다.
Prinmt 함수의 내부인 8라인에서 또 다시 Print 함수를 호출하고 있다.
이 때 count를 1 감소시켜 호출함으로써 0에 도달할 경우 문자열 출력 및 Print 함수의 호출을 멈추게 된다
#include <stdio.h>
void Print(char *str, int count)
{
if (count <= 0)
return;
printf("%s\n", str);
Print(str, count - 1);
}
int main(void)
{
Print("recursive function", 5);
return 0;
}
*/
#include <stdio.h>
int power(int x, int y)
{
if (y > 0)
return x * power(x, y - 1); //재귀 함수
else
return 1;
}
int main(void)
{
int a = 2;
int b = 3;
int result = power(a, b);
printf("%d^%d:%d\n", a, b, result);
a = 3;
b = 4;
result = power(a, b);
printf("%d^%d:%d\n", a, b, result);
return 0;
}
[1.10]
/*
다음 프로그램에서 Print 함수는 첫 번째 매개변수로 int형 배열을 받고 있다.
그런데 const 포인터로 선언하고 있다.
여기서 프로그래머가 const로 선언한 의도가 무엇인지 설명해본다
*/
#include <stdio.h>
void Print(const int *ary, int count)
//const로 선언한 이유: 전달받은 배열의 내용이 변하지 않도록 const로 선언하였다.
//const 키워드를 삭제하면 컴파일되지 않는 이유:ary1 배열이 const로 선언되었기 때문이다.
{
int i;
for (i = 0; i < count; i++)
printf("%d ", ary[i]);
printf("\n");
}
int main(void)
{
const int ary1[3] = { 1, 2, 3 };
int ary2[5] = { 4, 5, 6, 7, 8 };
Print(ary1, 3);
Print(ary2, 5);
return 0;
}
[1.11]
/*
struct Point를 사용하여 다음과 같은 프로그램을 작성한다.
swap 함수를 작성하되 기존의 int형을 struct Point형으로만 대체하면 된다.
그 결과는 두 개의 구조체 변수의 값이 교체되는 것이며 int형일 때와 마찬가지로 실매개 변수의 값도 교체되어야 한다.
여기서 swap 함수는 생각하는 것보다 훨씬 간단하게 작성될 수 잇다는 것을 알아야 한다.
int형에 대한 swap과 내용 상 다를 바가 없다.
*/
#include <stdio.h>
struct Point
{
int x;
int y;
};
void Swap(struct Point &p1, struct Point &p2) //참조형 전달
{
struct Point temp = p1;
p1 = p2;
p2 = temp;
}
int main(void)
{
struct Point p1 = { 1, 2 };
struct Point p2 = { 3, 4 };
printf("구조체 p1:[%d, %d]\n", p1.x, p1.y);
printf("구조체 p2:[%d, %d]\n", p2.x, p2.y);
printf("변경 후\n");
Swap(p1, p2);
printf("구조체 p1:[%d, %d]\n", p1.x, p1.y);
printf("구조체 p2:[%d, %d]\n", p2.x, p2.y);
return 0;
}
[1.12]
/*
양방향 링크드 리스트를 사용하여 [그림 1.10]과 같은 트리를 만들어 본다.
노드로 추가될 데이터는 int형 변수이며 사용자로부터 5회 입력을 받아들인다.
각 입력 시마다 새로운 노드를 생성하고 현재 트리에 삽입하면 되는데 삽입 기준은 다음과 같다.
만약 추가해야 할 노드의 data 값이 root노드의 data 값보다 작다면 왼쪽으로 이동하고, 같거나 크다면 오른쪽으로 이동하도록 한다.
그리고 이동한 노드를 대상으로 동일한 과정을 반복하여 말단 노드까지 이동한 후 해당 위치에 삽입하면 된다.
마지막으로 트리 상의 가장 왼쪽 노드로부터 시작하여 오른쪽으로 이동하면서 차례로 해당 노드의 data 값을 출력한다.
출력 결과는 data 값들의 오름차순으로 출력되어야 한다.
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node *left; //왼쪽
struct _node *right; //오른쪽
}Node;
void InorderTraverse(Node *Root) //중위순회
{
if (Root == NULL)
return;
InorderTraverse(Root->left);
printf("%d ", Root->data);
InorderTraverse(Root->right);
}
int main(void)
{
int i;
Node *Root = NULL; //루트 노드
Node *InitialRoot; //기존 루트노드
Node *Parent = NULL; //부모 노드
Node *Current;
for (i = 1; i <= 5; i++)
{
//노드 생성
Current = (Node*)malloc(sizeof(Node));
Current->data = rand() % 10 + 1;
printf("%d번째 데이터:%d\n", i, Current->data);
Current->left = NULL;
Current->right = NULL;
if (Root == NULL)
{
Root = Current;
printf("%d번째 노드 루트에 저장되었습니다\n", i);
InitialRoot = Root; //기존 루트노드 저장
continue;
}
while (1)
{
Parent = InitialRoot;
printf("InitialRoot:%d\n", InitialRoot->data);
if (InitialRoot->data > Current->data)
{
if (InitialRoot->left) //왼쪽 데이터가 존재한다면
InitialRoot = InitialRoot->left;
else //데이터 삽입
{
InitialRoot->left = Current;
printf("%d번째 데이터 왼쪽으로 갔습니다\n", i);
break;
}
}
else
{
if(InitialRoot->right)
InitialRoot = InitialRoot->right;
else
{
InitialRoot->right = Current;
printf("%d번째 데이터 오른쪽으로 갔습니다\n", i);
break;
}
}
}
Parent = Current;
InitialRoot = Root; //초기화
}
InorderTraverse(InitialRoot);
return 0;
}
[1.13]
/*
다음 프로그램은 컴파일이 되지 않는 불완전한 프로그램이다.
또한 논리적으로 문제가 있는 프로그램이다.
Visual C++ 11.0을 사용하여 이 프로그램을 작성하고 디버깅해본다.
*/
#include <stdio.h>
struct Point
{
int x, y;
};
struct Point GetSum(const struct Point *pAry, int count)
{
int i;
struct Point Po = { 0, 0 };
for (int i = 0; i <= count; i++)
{
Po.x += pAry[i].x;
Po.y += pAry[i].y;
}
return Po;
}
int main(void)
{
//struct Point Ary[3] = { {1, 1}, {2, 2}, {3, 3}, {4, 4} }; //주석 처리 된 부분이 틀린 부분
const struct Point Ary[4] = { {1,1}, {2,2}, {3,3}, {4,4} };
struct Point PSum = GetSum(Ary, 3);
printf("Sum:[%d, %d]\n", PSum.x, PSum.y);
return 0;
}
개발 환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
[참고] 기초를 탄탄히 세워주는 C++ 프로그래밍 입문 황준하 저
'C++ > 기초를 탄탄히 세워주는 C++ 프로그래밍 입문(황준하 저)' 카테고리의 다른 글
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 5장 연습문제 (0) | 2017.06.29 |
---|---|
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 4장 연습문제 (0) | 2017.06.27 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 3장 연습문제 (0) | 2017.06.21 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 2장 연습문제 (0) | 2017.06.20 |
또 C++ 입문책을 보는 이유 (0) | 2017.06.19 |