공부할 책 : 자료구조와 함께 배우는 알고리즘 입문 - C언어 편
내년 2학년때 자료구조랑 알고리즘 배운다! 예습해둬야지 히히
문제를 해결하기 위한 것으로, 명확하게 정의되고 순서가 있는 유한 개의 규칙으로 이루어진 집합
#include <stdio.h>
int max4(int a, int b, int c, int d)
{
int max = a;
if (b > max) max = b;
if (c > max) max = c;
if (d > max) max = d;
return max;
}
int main(void)
{
int a, b, c, d;
scanf_s("%d %d %d %d", &a,&b,&c,&d);
printf("최댓값은 %d입니다.\n", max4(a, b, c, d));
}
#include <stdio.h>
int min3(int a, int b, int c)
{
int min = a;
if (min > b) min = b;
if (min > c) min = c;
return min;
}
int main(void)
{
int a, b, c;
scanf_s("%d %d %d", &a,&b,&c);
printf("최솟값은 %d입니다.\n", min3(a, b, c));
}
쉬우니 생략
#include <stdio.h>
int min3(int a, int b, int c)
{
if (a >= b)
if (b >= c)
return b;
else if (a <= c)
return a;
else
return c;
else if (a > c)
return a;
else if (a < c)
return c;
else
return b;
}
int main(void)
{
printf("min3(%d, %d, %d) = %d\n", 3, 2, 1, min3(3, 2, 1)); /* [A] a > b > c */
printf("min3(%d, %d, %d) = %d\n", 3, 2, 2, min3(3, 2, 2)); /* [B] a > b = c */
printf("min3(%d, %d, %d) = %d\n", 3, 1, 2, min3(3, 1, 2)); /* [C] a > c > b */
printf("min3(%d, %d, %d) = %d\n", 3, 2, 3, min3(3, 2, 3)); /* [D] a = c > b */
printf("min3(%d, %d, %d) = %d\n", 2, 1, 3, min3(2, 1, 3)); /* [E] c > a > b */
printf("min3(%d, %d, %d) = %d\n", 3, 3, 2, min3(3, 3, 2)); /* [F] a = b > c */
printf("min3(%d, %d, %d) = %d\n", 3, 3, 3, min3(3, 3, 3)); /* [G] a = b = c */
printf("min3(%d, %d, %d) = %d\n", 2, 2, 3, min3(2, 2, 3)); /* [H] c > a = b */
printf("min3(%d, %d, %d) = %d\n", 2, 3, 1, min3(2, 3, 1)); /* [I] b > a > c */
printf("min3(%d, %d, %d) = %d\n", 2, 3, 2, min3(2, 3, 2)); /* [J] b > a = c */
printf("min3(%d, %d, %d) = %d\n", 1, 3, 2, min3(1, 3, 2)); /* [K] b > c > a */
printf("min3(%d, %d, %d) = %d\n", 2, 3, 3, min3(2, 3, 3)); /* [L] b = c > a */
printf("min3(%d, %d, %d) = %d\n", 1, 2, 3, min3(1, 2, 3)); /* [M] c > b > a */
return 0;
}
int med3 (int a, int b, int c)
{
if ((b >= a && c <= a) || (b <=a && c>= a))
return a;
else if ((a > b && c < b) || (a < b && c > b))
return b;
return c;
}
내 답안 : 모르겠음..
모범답안 : 첫 번째 if가 성립하지 않는 경우 두 번째 if 에서도 같은 판단을 하므로 효율적이지 않다.
Q6 생략
#include <stdio.h>
int main(void)
{
int num1, sum = 0;
scanf_s("%d", &num1);
for (int i = 1;i <= num1;i++) {
sum += i;
printf("%d ",i);
if (i != num1) {
printf("+ ");
}
}
printf("= %d", sum);
}
#include <stdio.h>
int main(void)
{
int num1;
scanf_s("%d", &num1);
printf("%d", (1 + num1) * 5);
}
쉬워서 생략
#include <stdio.h>
int main(void)
{
int a, b;
scanf_s("%d", &a);
do{
scanf_s("%d", &b);
if (a > b) {
printf("a보다 큰 값을 입력하세요!");
}
} while (a > b);
printf("%d", b - a);
}
#include <stdio.h>
int main(void)
{
int a,b=0;
scanf_s("%d", &a);
while (a > 0) {
a = a / 10;
b++;
}
printf("그 수는 %d자리 입니다.", b);
}
하나의 입구와 하나의 출구를 가진 구성 요소만을 계층적으로 배치하여 프로그램을 구성하는 방법을 구조적 프로그래밍이라 한다. 구조적 프로그래밍은 순차, 선택, 반복이라는 3종류의 제어 흐름을 사용한다.
Q12~Q16 쉬워서 생략
#include <stdio.h>
void spira(int n) {
for (int i = 0;i < n;i++) {
for (int j = n - i;j > 0;j--) {
printf(" ");
}
for (int k = 0;k < (i + 1) * 2 - 1;k++) {
printf("*");
}
printf("\n");
}
}
int main(void)
{
int a;
scanf_s("%d", &a);
spira(a);
}
#include <stdio.h>
void spira(int n) {
for (int i = 0;i < n;i++) {
for (int j = 1;j <= i;j++) {
printf(" ");
}
for (int k = 1+i*2;k <= n * 2 - 1;k++) {
printf("%d", i+1);
}
printf("\n");
}
}
int main(void)
{
int a;
scanf_s("%d", &a);
spira(a);
}
데이터 단위와 데이터 자체 사이의 물리적 또는 논리적인 관계
같은 자료형의 변수로 이루어진 요소가 모여 직선 모양으로 줄지어 있는 자료구조
배열 요소의 자료형은 int형이나 double형 등 상관 없음
그러나 배열 선언 시 요소 개수는 상수만 사용 가능. int a[n] 처럼 사용 불가
그런데 마치 변수를 사용해 배열을 선언한 것처럼 할 수 있다.
형식 :
void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
calloc 함수 : 크기가 size인 자료가 nmemb개만큼 들어갈 메모리를 할당한다. 할당한 메모리 영역은 모든 비트가 0으로 초기화된다.
malloc 함수 : 크기가 size인 메모리를 할당한다. 할당한 메모리의 값은 정의되지 않는다.
데이터(Data) 영역 - 전역 변수와 정적 변수가 할당되는 영역
스택(Stack) 영역 - 함수 호출 시 생성되는 지역 변수와 매개변수가 저장되는 영역
힙(Heap) 영역 - 필요에 따라 동적으로 메모리 할당. 프로그램 실행 중에 결정
여기서 calloc, malloc 함수는 힙(heap)이라는 특별한 빈 공간에 기억 장소를 확보한다. 이때 확보한 메모리가 불필요하면 그 공간을 해제해야 한다. 이를 위해 제공되는 함수가 free 함수이다.
형식 :
void free(void *ptr);
실습 코드 1 :
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int * x;
x = calloc(1, sizeof(int)); /* int형 포인터에 메모리 할당 */
if (x == NULL) {
puts("메모리 할당에 실패했습니다.");
}
else {
*x = 57;
printf("*x = %d\n", *x);
free(x); /* int형 포인터에 할당한 메모리 해제 */
}
return 0;
}
실습 코드 2 :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i;
int *a; /* 배열의 첫 번째 요소의 포인터 */
int na; /* 배열 a의 요솟수 */
printf("요솟수 : ");
scanf("%d", &na);
a = calloc(na, sizeof(int)); /* 요소 개수가 na인 int형 배열을 생성 */
if (a == NULL)
puts("메모리 확보에 실패했습니다.");
else {
printf("%d개의 정수를 입력하세요.\n", na);
for (i = 0; i < na; i++) {
printf("a[%d] : ", i);
scanf("%d", &a[i]);
}
printf("각 요솟값은 아래와 같습니다.\n");
for (i = 0; i < na; i++)
printf("a[%d] = %d\n", i, a[i]);
free(a); /* 요소 개수가 na인 int형 배열을 해제 */
}
return 0;
}
모든 자료형의 메모리 확보 또는 해제에 사용한다. 이때 특정 자료형의 포인터를 주고받을 때 자료형이 서로 맞지 않으면 문제가 발생하므로 void 포인터를 반환하거나 받는 데 사용한다. void 포인터는 모든 형의 객체를 가리킬 수 있다. void 포인터의 값을 모든 자료형의 포인터에 대입할 수 있고, 거꾸로 모든 자료형의 포인터 값을 void 포인터에 대입할 수 있다.
쉬운건 생략
/* 배열 요소의 최댓값을 구합니다(값을 입력합니다). */
#include <stdio.h>
#include <stdlib.h>
/*--- 요솟수가 n인 배열 a의 요소의 최댓값을 구합니다. ---*/
int minof(const int a[], int n) {
int min = a[0];
for (int i = 1;i < n;i++) {
if (min > a[i]) min = a[i];
}
return min;
}
int main(void)
{
int i;
int *height; /* 배열의 첫 번째 요소의 포인터 */
int number; /* 인원 = 배열 height의 요소 개수 */
printf("사람 수 : ");
scanf_s("%d", &number);
height = calloc(number, sizeof(int)); /* 요솟수가 number개인 배열을 생성 */
printf("%d 사람의 키를 입력하세요.\n", number);
for (i = 0; i < number; i++) {
printf("height[%d] : ", i);
scanf_s("%d", &height[i]);
}
printf("최댓값은 %d입니다.\n", minof(height, number));
free(height); /* 배열 height를 해제 */
return 0;
}
Q3,Q4 비슷해서 생략
Q5. 역순 정렬
#define swap(type, x, y) do { type t = x; x = y; y = t;} while (0)
void ary_reverse(int a[], int n)
{
int i;
for (i = 0;i < n/2;i++) {
for (int j = 0;j < n;j++) {
printf("%d ", a[j]);
}
printf("\n");
swap(int, a[i], a[n - i - 1]);
printf("a[%d]와 a[%d]를 교환합니다.\n", i, n - i - 1);
}
printf("역순정렬 종료!\n");
}
int main() {
int i;
int* x;
int nx;
scanf_s("%d", &nx);
x = calloc(nx, sizeof(int));
printf("배열 입력 :\n");
for (i = 0;i < nx;i++) {
scanf_s("%d", &x[i]);
}
ary_reverse(x, nx);
for (i = 0;i < nx;i++) {
printf("%d\n", x[i]);
}
free(x);
}
#include <stdio.h>
int main() {
int i, n;
unsigned long counter = 0;
for (n = 2;n <= 1000;n++) {
for (i = 2;i < n;i++) {
counter++;
if (n % i == 0)
break;
}
if (n == i)
printf("%d\n", n);
}
printf("나눗셈을 실행한 횟수 : %d", counter);
return 0;
}
나눗셈 실행 횟수 : 78022
#include <stdio.h>
int main() {
int i, n;
int prime[500];
int ptr = 0;
unsigned long counter = 0;
prime[ptr++] = 2;
for (n = 3;n <= 1000;n += 2) {
for (i = 1;i < ptr;i++) {
counter++;
if (n % prime[i] == 0)
break;
}
if (ptr == i)
prime[ptr++] = n;
printf("%d\n", n);
}
printf("나눗셈 실행 횟수 : %lu\n", counter);
}
나눗셈 실행 횟수 : 14622
#include <stdio.h>
int main(void)
{
int i, n;
int prime[500];
int ptr = 0;
unsigned long counter = 0;
prime[ptr++] = 2;
prime[ptr++] = 3;
for (n = 5;n <= 1000;n += 2) {
int flag = 0;
for (i = 1;counter++, prime[i] * prime[i] <= n;i++) {
counter++;
if (n % prime[i] == 0) {
flag = 1;
break;
}
}
if (!flag)
prime[ptr++] = n;
}
for (i = 0;i < ptr;i++)
printf("%d\n", prime[i]);
printf("곱셈과 나눗셈을 실행한 횟수 : %lu\n", counter);
return 0;
}
곱셈/나눗셈 실행한 횟수 : 3774