쉽풀C - 11장 포인터

2023. 2. 7. 20:49·Category/C
728x90

1. 포인터를 이용하여 자기가 사용하는 CPU의 바이트 순서를 살펴보는 프로그램을 작성해보자. 바이트 순서(byte ordering, endian)은 컴퓨터의 메모리에 바이트를 배열하는 방법이다. 바이트 순서는 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있다. 아래의 프로그램에 주석을 추가하라.

종류 0x12345678의 표현
빅 엔디언 12 34 56 78
리틀 엔디언 78 56 34 12
#include<stdio.h>

int main(void) {
	int x = 0x12345678;
	unsigned char* xp = (char*)&x;

	// 인텔 CPU는 리틀 엔디언이다. 
	printf("바이트 순서: %x %x %x %x\n", xp[0], xp[1], xp[2], xp[3]);
	return 0;
}

 

 

2. 2개의 정수의 합과 차를 동시에 반환하는 함수를 작성하고 테스트하라. 포인터 매개 변수를 사용한다.

#include<stdio.h>

void get_sum_diff(int x, int y, int* p_sum, int* p_diff); 

int main(void) {
	int sum, diff;

	get_sum_diff(100, 200, &sum, &diff);
	printf("원소들의 합=%d\n원소들의 차=%d\n", sum, diff);
	
	return 0;
}

// 2개의 정수의 합과 차를 동시에 반환하는 함수
void get_sum_diff(int x, int y, int* p_sum, int* p_diff) {
	*p_sum = x + y;
	*p_diff = x - y;
}

 

 

3. 정수 배열을 받아서 요소들을 난수로 채우는 함수를 작성하고 테스트하라. 난수는 라이브러리 함수인 rand()를 사용하여 생성한다.

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10

void array_fill(int* A, int size); // 정수 배열을 받아서 요소들을 난수로 채우는 함수

int main(void) {
	int array[SIZE];

	srand((unsigned)time(NULL)); // 난수 생성을 위한 시드 설정

	array_fill(array, SIZE);

	for (int i = 0; i < SIZE; i++)
		printf("%d ", *(array + i)); // array[i]와 같음
	
	return 0;
}

void array_fill(int* A, int size) {
	for (int i = 0; i < size; i++) {
		*A = rand();
		A++;
	}
}

 

 

4. 정수 배열의 요소들을 화면에 출력하는 함수를 작성하고 테스트하라. 출력 형식은 A[ ] = { 1, 2, 3, 4, 5 }와 같은 형식이 되도록 하라.

#include<stdio.h>
#define SIZE 10

void array_print(int* A, int size); // 정수 배열의 요소들을 화면에 출력하는 함수

int main(void) {
	int array[SIZE] = { 1,2,3,4 }; // 나머지 6개 요소들은 0으로 초기화

	array_print(array, SIZE);	
	return 0;
}

void array_print(int* A, int size) {
	printf("A[] = { ");
	for (int i = 0; i < size; i++) 
		printf("%d ", *(A + i));
	printf("}\n");
}

 

 

5. 학생들의 평점은 4.3점이 만점이라고 하자. 배열 grades[ ]에 학생 10명의 학점이 저장되어 있다. 이것을 100점 만점으로 변환하여서 배열 scores[ ]에 저장하는 함수를 작성하고 테스트하라.

#include<stdio.h>
#define STUDENT 10 // 학생의 수

void convert(double* grades, double* scores, int size); // 학점 변환 함수
void print_array(double* A, int size); // 배열 출력 함수

int main(void) {
	double grades[STUDENT] = { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.3 };
	double scores[STUDENT];

	convert(grades, scores, STUDENT);

	print_array(grades, STUDENT); 
	print_array(scores, STUDENT);
	
	return 0;
}

void convert(double* grades, double* scores, int size) {
	for (int i = 0; i < size; i++)
		*(scores + i) = *(grades + i) * 100. / 4.3; // 점수 변환은 비례식을 사용. 즉 100:4.3=x:y
}

void print_array(double* A, int size) {
	for (int i = 0; i < size; i++)
		printf("%0.2lf ", *(A + i));
	printf("\n");
}

 

 

6. 정수 배열 A[ ]를 다른 정수 배열 B[ ]에 복사하는 함수를 작성하고 테스트하라.

#include<stdio.h>
#define SIZE 10

void array_copy(int* A, int* B, int size); // 정수 배열 A[]를 정수 배열 B[]에 복사하는 함수
void print_array(int* A, int size); // 정수 배열 출력 함수

int main(void) {
	int A[SIZE] = { 1,2,3 };
	int B[SIZE];

	array_copy(A, B, SIZE); // 배열 A를 배열 B에 복사
	print_array(A, SIZE); // 배열 A 출력
	print_array(B, SIZE); // 배열 B 출력

	return 0;
}

void array_copy(int* A, int* B, int size) {
	int i;
	for (i = 0; i < size; i++)
		*(B + i) = *(A + i);
}

void print_array(int* A, int size) {
	int i;
	printf("A[] = ");
	for (i = 0; i < size; i++)
		printf("%d ", *(A + i));
	printf("\n");
}

 

 

7. 직원들의 기본급이 배열 A[ ]에 저장되어 있다. 배열 B[ ]에는 직원들의 보너스가 저장되어 있다. 기본급과 보너스를 합하여 이번달에 지급할 월급의 총액을 계산하고자 한다. A[ ]와 B[ ]를 더하여 배열 C[ ]에 저장하는 함수를 작성하고 테스트하라. 즉 모든 i에 대하여 C[i] = A[i] + B[i]가 된다.

#include<stdio.h>
#define SIZE 10

void array_add(int* A, int* B, int* C, int size); // 배열 A와 배열 B를 더하여 배열 C에 저장하는 함수
void print_array(int* A, int size); // 정수 배열 출력 함수

int main(void) {
	int A[SIZE] = { 1,2,3 };
	int B[SIZE] = { 0 };
	int C[SIZE];

	array_add(A, B, C, SIZE); 

	printf("A[] = ");
	print_array(A, SIZE); // 배열 A 출력

	printf("B[] = ");
	print_array(B, SIZE); // 배열 B 출력

	printf("C[] = ");
	print_array(C, SIZE); // 배열 C 출력

	return 0;
}

void array_add(int* A, int* B, int* C, int size) {
	int i;
	for (i = 0; i < size; i++)
		*(C + i) = *(A + i) + *(B + i);
}

void print_array(int* A, int size) {
	int i;
	for (i = 0; i < size; i++)
		printf("%d ", *(A + i));
	printf("\n");
}

 

 

8. 직원들의 월급이 배열 A[ ] 에 저장되어 있다고 가정하자. 이번 달에 회사에서 지급할 월급의 총액을 계산하고자 한다. 정수형 배열 요소들의 합을 구하여 반환하는 함수를 작성하고 테스트하라.

#include<stdio.h>
#define SIZE 10

int array_sum(int* A, int size); // 정수형 배열 요소들의 합을 구하여 반환하는 함수
void print_array(int* A, int size); // 정수 배열 출력 함수

int main(void) {
	int A[SIZE] = { 1,2,3 };

	printf("A[] = ");
	print_array(A, SIZE); // 배열 A 출력

	printf("월급의 합=%d\n", array_sum(A, SIZE));

	return 0;
}

int array_sum(int* A, int size) {
	int sum = 0;
	for (int i = 0; i < size; i++)
		sum += *(A + i);
	return sum;
}

void print_array(int* A, int size) {
	int i;
	for (i = 0; i < size; i++)
		printf("%d ", *(A + i));
	printf("\n");
}

 

 

9. 직원들의 월급이 저장된 배열에서 월급이 200만 원인 사람을 찾고 싶을 때가 있다. 주어진 값을 배열 A[ ]에서 탐색하여 배열 요소의 인덱스를 반환하는 함수를 작성하고 테스트하라.

#include<stdio.h>
#define SIZE 5

int search(int* A, int size, int search_value); 

int main(void) {
	int salary[SIZE] = { 100,200,300,400,500 };
	int index;

	index = search(salary, SIZE, 200);
	if (index == -1)
		printf("같은 값을 찾지 못했습니다.\n");
	else
		printf("월급이 200만원인 사람의 인덱스=%d\n", index);

	return 0;
}

// 주어진 값을 배열 A에서 찾아 인덱스를 반환하는 함수
int search(int* A, int size, int search_value) {
	int i;
	for (i = 0; i < size; i++) {
		if (*(A + i) == search_value) // 같은 값이 있는 경우
			return i; // 인덱스 값을 반환
	}
	return -1; // 주어진 값을 찾지 못한 경우 -1 반환
}

 

 

10. 2개의 정수를 입력받아서 최대 공약수와 최소 공배수를 반환하는 함수를 작성하고 테스트하라. 최대 공약수는 유클리드의 방법을 사용하여서 계산한다.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void get_lcm_gcd(int x, int y, int* p_lcm, int* p_gcd);
int get_gcd(int x, int y);

int main(void) {
	int x, y;
	int lcm; // 최소 공배수
	int gcd; // 최대 공약수

	printf("두 개의 정수를 입력하시오: ");
	scanf("%d %d", &x, &y);

	get_lcm_gcd(x, y, &lcm, &gcd);

	printf("최소공배수는 %d입니다.\n", lcm);
	printf("최대공약수는 %d입니다.\n", gcd);

	return 0;
}

// 두 개의 정수를 입력받아서 최대 공약수와 최소 공배수를 반환하는 함수
void get_lcm_gcd(int x, int y, int* p_lcm, int* p_gcd) {
	int max = (x > y) ? x : y; // x와 y 중 더 큰 수
	int min = (x < y) ? x : y; // x와 y 중 더 작은 수

	x = max, y = min;
	*p_gcd = get_gcd(x, y); // 최대 공약수 구하기
	*p_lcm = (x * y) / *(p_gcd); // 최소 공배수 구하기
}

// 순환 호출을 이용하여 최대 공약수를 구하는 함수. x는 y보다 커야 함.
int get_gcd(int x, int y) {
	if (y == 0)
		return x;
	else
		return get_gcd(y, x % y);
}

 

 

11. 2개의 정렬된 정수 배열 A[ ]와 B[ ]가 있다고 가정하자. 이 2개의 배열을 합쳐서 하나의 정렬된 배열 C[ ]로 만드는 함수를 작성하고 테스트한다. 다음과 같은 함수 원형을 가진다고 가정하라.

#include<stdio.h>

void merge(int* A, int* B, int* C, int size);
void print_array(int* A, int size); // 배열 출력 함수

int main(void) {
	int A[] = { 2,5,7,8 };
	int B[] = { 1,3,4,6 };
	int C[8];

	merge(A, B, C, 4); // 배열 A와 배열 B를 합쳐서 배열 C에 저장(작은 순서대로)

	printf("A[] = ");
	print_array(A, 4); // 배열 A 출력

	printf("B[] = ");
	print_array(B, 4); // 배열 B 출력

	printf("C[] = ");
	print_array(C, 8); // 배열 C 출력

	return 0;
}

void merge(int* A, int* B, int* C, int size) {
	int ai = 0, bi = 0, ci = 0; // 각각 배열 A, B, C의 인덱스
	for (; ai < size && bi < size;) {
		// 배열 A와 배열 B중 작은 값을 배열 C에 저장한다.
		if (A[ai] < B[bi]) {
			C[ci++] = A[ai++];
		}
		else {
			C[ci++] = B[bi++];
		}
	}
	for (; ai < size; ci++) { // A 배열의 값이 남아있으면 C 배열에 차례로 모두 저장
		C[ci] = A[ai++];
	}
	for (; bi < size; ci++) { // B 배열의 값이 남아있으면 C 배열에 차례로 모두 저장
		C[ci] = B[bi++];
	}
}

void print_array(int* A, int size) {
	int i;
	for (i = 0; i < size; i++)
		printf("%d ", *(A + i));
	printf("\n");
}

 

 

12. 우리가 프로그램을 하다보면 사용자로부터 2개의 정수를 받아오는 경우가 많다. 이것을 함수로 구현해두고 필요할 때마다 사용하면 편리할 것이다. 하지만 한 가지 문제가 있다. C에서 함수는 하나의 값만 반환할 수 있다. 2개 이상의 값을 반환하려면 다른 방법을 사용해야 하는데 다음과 같이 포인터도 사용할 수 있다.

위와 같은 원형을 가지는 함수를 작성하고 이것을 이용해서 정수의 합을 계산하는 프로그램을 작성해보자.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define SIZE 50

void get_int(int* px, int* py); // 2개의 정수 값을 반환하는 함수

int main(void) {
	int x, y;

	get_int(&x, &y);
	printf("정수의 합은 %d\n", x + y);

	return 0;
}

void get_int(int* px, int* py) {
	printf("2개의 정수를 입력하시오(예: 10 20): ");
	scanf("%d %d", px, py);
}
728x90

'Category > C' 카테고리의 다른 글

쉽게 풀어쓴 C언어 - 15장 스트림과 파일 입출력  (0) 2023.02.12
쉽게 풀어쓴 C언어 Express - 14장 포인터 활용  (0) 2023.02.11
쉽풀C - 10장 배열  (0) 2023.02.06
쉽풀C - 9장 함수와 변수  (0) 2023.02.05
쉽풀C - 8장 함수  (0) 2023.02.04
'Category/C' 카테고리의 다른 글
  • 쉽게 풀어쓴 C언어 - 15장 스트림과 파일 입출력
  • 쉽게 풀어쓴 C언어 Express - 14장 포인터 활용
  • 쉽풀C - 10장 배열
  • 쉽풀C - 9장 함수와 변수
Corinee
Corinee
  • Corinee
    Coding Note
    Corinee
  • 전체
    오늘
    어제
    • 분류 전체보기 (361) N
      • Category (354)
        • Algorithm (7)
        • SQL (2)
        • Java (4)
        • C (9)
        • React (7)
        • JavaScript (9)
        • CSS (2)
        • Node (1)
        • SpringBoot (26)
        • Database (3)
        • Network (1)
        • Django (6)
        • Python (22)
        • Flask (4)
        • iOS (25)
        • Swift (4)
        • Flutter (11)
        • Dart (3)
        • Git (1)
        • Firebase (1)
        • Gof (1)
        • 정보처리기사 (112)
        • AI (5)
        • NestJs (4)
        • Docker (1)
        • 사이드 프로젝트 (1)
        • Note (80)
        • Socket (1)
        • 개인 정보 처리 방침 (1)
        • 면접 (0)
        • Vue.js (0)
      • Archive (2) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    core web vitals
    원시값(primitive)
    mcp server
    inp
    Collections
    math.h
    시맨틱 버전(semantic versioning
    public vs assets
    named export vs default export
    useEffect
    chrome extension 자동 배포
    Jest
    ajax (asynchronous javascript and xml)
    쉽게 풀어쓴 C언어 Express
    stdlib.h
    x.y.z (메이저.마이너.패치)
    소프트웨어 버전 관리
    중첩 함수(nested function)
    react
    defaultdict
    counter
    styled-components
    json.parse(json.stringify())
    semver)
    structuredclone()
    프로세스 강제 종료
    react router
    jackson 라이브러리
    mermaid-cli
    intellij 콘솔 한글 깨짐
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Corinee
쉽풀C - 11장 포인터
상단으로

티스토리툴바