** 가로 행, 세로 열
** 다차원 배열
: TYPE arr[세로길이][가로길이];
** 2차원 배열도 메모리상에서는 1차원 형태로 존재
▲ int arr [3][2];
** 3차원 배열은 여러 개의 2차원 배열이 모여있는 형태
** **(포인터의 포인터, 더블 포인터)
: 포인터 변수를 가리키는 이중 포인터 변수
** 포인터 변수 대상의 Call-by-reference
void Swap (int* ptr1, int* ptr2)
{
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
▲ 두 변수에 저장된 값 바꾸기
void Swap (int* p1, int* p2)
{
int* temp = p1;
p1 = p2;
p2 = temp;
}
▲ 두 싱글 포인터 변수에 저장된 값을 바꾸기 - 실패
왜?
: p1과 p2는 바꿨지만,
이는 main에 있는 ptr1과 ptr2와는 별개의 변수이기 때문
void SwapIntPtr(int** dp1, int** dp2)
{
int* temp = *dp1;
*dp1 = *dp2;
*dp2 = temp;
}
▲ 두 싱글 포인터 변수에 저장된 값을 바꾸기 - 성공
성공 이유?
: 함수 내에서 포인터 변수 ptr1과 ptr2에직접 접근이 가능하여 두 변수에 저장된 값을 바꿔줘야 함
따라서 더블포인터 사용 필요 → 교환 성공
** 1차원 배열
int arr[10];
int* ptr = arr;
** 2차원 배열
int arr_2d[3][4];
int (*ptr)[4] = arr_2d;
** arr_2d는 첫 번째 요소를 가리키면서 배열 전체를 의미
arr_2d[0]는 첫 번째 요소를 가리키되 1행 만을 의미
** int (*ptr) [4];
ㄴ int : int형 변수를 가리키는 포인터
ㄴ (*ptr) : 포인터
ㄴ [4] : 포인터 연산시 4칸씩 건너뛰는 포인터
** 2차원 배열에서도 arr[i] == *(arr + i) 성립
** 포인터 배열과 배열 포인터는 혼동하기가 쉬움
1) 포인터 배열 : 배열 선언, int형 포인터 변수로 이뤄진 int형 포인터 배열
int 포인터_배열 = { &num1, &num2, &num3, &num4 };
2) 배열 포인터 : 포인터 변수 선언, 가로길이가 4인 int형 2차원 배열을 가리키는 용도의 포인터 변수
int (*배열_포인터)[4] = arr_2d;
** 함수 포인터
: 함수의 이름은 함수가 저장된 메모리 공간의 주소 값을 의미
ㄴ 함수의 이름도 그 형태가 상수임
** 함수 이름의 포인터 형(type)
: 반환형과 매개변수의 선언을 통해서 결정짓도록 약속
int SimpleFunc(int num) { /* 함수 몸통 */ }
1) 반환형이 int이고, 매개변수로 int형 변수 하나 선언된 포인터 형(type)
2) int (*fptr) (int)
ㄴ int : 반환형이 int인 함수 포인터
ㄴ (*fptr) : fptr은 포인터
ㄴ (int) : 매개변수 선언이 int 하나인 함수 포인터
** 형(type)이 존재하지 않는 void 포인터
: void형 포인터 변수에는 어떠한 변수의 주소 값이든 담을 수 있음, 함수의 주소 값도 포함
** void형 포인터 변수를 가지고는 아무런 포인터 연산도 하지 못한다.
ㄴ 값의 변경이나 참조도 불가능
ㄴ void형 포인터 변수에는 가리키는 대상에 어떠한 형(type) 정보도 담겨있지 않기 때문
ㄴ 일단 주소 값에만 의미를 두고, 포인터 형은 나중에 결정할 때 유용하게 사용
** main 함수로의 인자 전달
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Number of strings passed : %d\n", argc);
for (int i = 0; i < argc; i++)
printf("%d string : %s \n", i + 1, argv[i]);
return 0;
}
** void SimpleFunc(TYPE * arr) == void SimpleFunc(TYPE arr[])
void SimpleFunc(char** arr) == void SimpleFunc(char* arr[])
** 도전 프로그래밍3
1.
#include <stdio.h>
int main(void)
{
int arr1[4][4];
int arr2[4][4];
int arr3[4][4];
int arr4[4][4];
int num = 1;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
arr1[i][j] = num;
num += 1;
}
}
num = 1;
for (int i = 3; i >= 0; i--)
{
for (int j = 0; j < 4; j++)
{
arr2[j][i] = num;
num += 1;
}
}
num = 1;
for (int i = 3; i >= 0; i--)
{
for (int j = 3; j >= 0; j--)
{
arr3[i][j] = num;
num += 1;
}
}
num = 1;
for (int i = 0; i < 4; i++)
{
for (int j = 3; j >= 0; j--)
{
arr4[j][i] = num;
num += 1;
}
}
// 출력
for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
{
for (int j = 0; j < sizeof(arr1[i]) / sizeof(int); j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
printf("\n");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", arr2[i][j]);
}
printf("\n");
}
printf("\n");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", arr3[i][j]);
}
printf("\n");
}
printf("\n");
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", arr4[i][j]);
}
printf("\n");
}
return 0;
}
2.
#include <stdio.h>
// 4 X 4 고정
int main(void)
{
int arr1[4][4] = {};
int num = 1;
for (int idx = 0; idx < 2; idx++)
{
for (int i = 0 + idx; i < 4 - idx; i++)
{
printf("[%d][%d] : %d\n", 0 + idx, i, num);
arr1[0 + idx][i] = num;
num += 1;
}
printf("\n");
for (int i = 1 + idx; i < 4 - idx; i++)
{
printf("[%d][%d] : %d\n", i, 3 - idx, num);
arr1[i][3 - idx] = num;
num += 1;
}
printf("\n");
for (int i = 2 - idx; i >= 0 + idx; i--)
{
printf("[%d][%d] : %d\n", 3 - idx, i, num);
arr1[3 - idx][i] = num;
num += 1;
}
printf("\n");
for (int i = 2 - idx; i >= 1 + idx; i--)
{
printf("[%d][%d] : %d\n", i, 0 + idx, num);
arr1[i][0 + idx] = num;
num += 1;
}
printf("====================================\n");
}
printf("\n");
// 출력
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
return 0;
}
#include <stdio.h>
#include <math.h>>
int main(void)
{
// 유동적으로 input 받기
printf("input number : ");
int inputSize;
scanf("%d", &inputSize);
int arr1[inputSize][inputSize] = {};
const int frontNum = 0;
const int backNum = inputSize - 1;
int num = 1;
for (int idx = 0; idx < ceil(inputSize / 2.0f); idx++)
{
for (int i = 0 + idx; i < inputSize - idx; i++)
{
printf("[%d][%d] : %d\n", frontNum + idx, i, num);
arr1[frontNum + idx][i] = num;
num += 1;
}
printf("\n");
for (int i = 1 + idx; i < inputSize - idx; i++)
{
printf("[%d][%d] : %d\n", i, backNum - idx, num);
arr1[i][backNum - idx] = num;
num += 1;
}
printf("\n");
for (int i = backNum - 1 - idx; i >= 0 + idx; i--)
{
printf("[%d][%d] : %d\n", backNum - idx, i, num);
arr1[backNum - idx][i] = num;
num += 1;
}
printf("\n");
for (int i = backNum - 1 - idx; i > 0 + idx; i--)
{
printf("[%d][%d] : %d\n", i, frontNum + idx, num);
arr1[i][frontNum + idx] = num;
num += 1;
}
printf("====================================\n");
}
printf("\n");
// 출력
for (int i = 0; i < inputSize; i++)
{
for (int j = 0; j < inputSize; j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
return 0;
}
3.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Range of random numbers: 0 ~ %d\n", RAND_MAX);
for (int i = 0; i < 5; i++)
{
printf("Random number output : %d\n", rand());
}
printf("\n\n================================\n");
for (int i = 0; i < 5; i++)
{
printf("Random number output : %d\n", (rand() % 99) + 1);
}
return 0;
}
4.
** 도전 3에서 사용한 난수는 출력되는 난수가 규칙적이라는 것
ㄴ 즉, rand 함수는 pseudo-random number → 난수를 흉내내기 위한 알고리즘으로 생성된 값
https://ko.wikipedia.org/wiki/%EC%9C%A0%EC%82%AC%EB%82%9C%EC%88%98
** 규칙적인 rand 함수를 극복하고자 나온 srand 함수
: 발생한 난수의 씨드 값 지정 필요 → 매번 시드값 받는거 귀찮 → 주로, 시스템 시간 받아서 사용
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int seed;
printf("input seed value : ");
scanf("%d", &seed);
// 1. 시드를 심는다
srand(seed);
for (int i = 0; i < 5; i++)
{
// 2. 열매를 수확한다
printf("Random number output : %d\n", rand());
}
printf("\nUse current time===========\n");
// 현재 시간을 이용해서 난수 출력해보기
srand((int)time(NULL));
for (int i = 0; i < 5; i++)
{
// 2. 열매를 수확한다
printf("Random number output : %d\n", rand());
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand((int)time(NULL));
for (int i = 0; i < 2; i++)
{
printf("The result of dice %d : %d\n", i + 1, rand() % 6 + 1);
}
return 0;
}
5.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int same = 0, win = 0;
int whileFlag = 1;
srand((int)time(NULL));
while (whileFlag)
{
int inputValue;
printf("rock 1, scissors 2, paper 3 : ");
scanf("%d", &inputValue);
const int computer = rand() % 3 + 1;
printf("computer : %d / me : %d\n", computer, inputValue);
if (inputValue == computer)
{
printf("same\n");
same += 1;
continue;
}
switch (inputValue)
{
case 1:
{
if (computer == 3)
{
printf("you select rock, computer select paper, you lose.\n");
whileFlag = 0;
break;
}
printf("you select rock, computer select scissors, you win.\n");
win += 1;
break;
}
case 2:{
if (computer == 1)
{
printf("you select scissors, computer select rock, you lose.\n");
whileFlag = 0;
break;
}
printf("you select scissors, computer select paper, you win.\n");
win += 1;
break;
}
case 3:{
if (computer == 2)
{
printf("you select paper, computer select scissors, you lose.\n");
whileFlag = 0;
break;
}
printf("you select paper, computer select rock, you win.\n");
win += 1;
break;
}
default:
break;
}
}
printf("win : %d, same : %d\n", win, same);
return 0;
}
6.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand((int)time(NULL));
for (int i = 0; i < 3; i++)
{
int inputNum[3];
printf("Select three numbers(0 ~ 9) : ");
scanf("%d %d %d", &inputNum[0], &inputNum[1], &inputNum[2]);
const int computer[3] = {
rand() % 9, rand() % 9, rand() % 9
};
printf("computer number : %d, %d, %d\n", computer[0], computer[1], computer[2]);
int strike = 0, ball = 0;
for (int j = 0; j < 3; j++)
{
if (inputNum[j] == computer[j])
{
strike += 1;
continue;
}
ball += 1;
}
printf("strike : %d, ball : %d\n", strike, ball);
}
return 0;
}
** 해당 글은 윤성우의 열혈 C프로그래밍 도서를 읽고 정리한 글입니다.
'IT공부 > IT서적' 카테고리의 다른 글
[윤성우 열혈 C++프로그래밍] Part2. 객체지향의 도입 (0) | 2024.08.15 |
---|---|
[윤성우 열혈 C++프로그래밍] Part1. c++로의 전환 (0) | 2024.08.08 |
[윤성우 열혈 C프로그래밍] Part4. C언어의 깊은 이해 (0) | 2024.07.28 |
[윤성우 열혈 C프로그래밍] Part2. 포인터 배열의 시작 (0) | 2024.07.19 |
[윤성우 열혈 C프로그래밍] Part1. C 언어의 기본 (0) | 2024.07.16 |