리턴 할 필요가 없는 함수에 사용된다.
리턴형을 void
로 설정
int main()
{
//void a; //메모리상에 얼마만큼의 공간을 줘야하는지 모름
void* b; //포인트라서 메모리상에 64비트 기준 8바이트 할당됨(오직 주소값만 할당)
double c = 123.3;
//a = 3; 오류발생
b = &c;
printf("%lf", *(double*)b); //void 포인터의 주소값은 double 포인터의 주소값으로 형변환
return 0;
}
b가 가르키는 주소형은 double형 변수의 주소값이라 생각한다.
#include <stdio.h>
int main()
{
int arr[1] = { 0x12345678};
printf("%x \n", arr[0]);
read_char(arr, 4);
return 0;
}
int read_char(void* p, int byte)
{
do {
printf("%x \n", *(char*)p);
byte--;
p = (char*)p + 1;
} while (p && byte);
return 0;
}
78부터 나오는건 리틀엔디안 방식으로 작동하기 때문이다. arr를 받아올때 void형식으로 받아와서 char포인터 형식으로 +1을 해주면 주소가 하나씩 증가한다.
#include <stdio.h>
int main(int argc, char **argv)
{
printf("받은 인자의 개수 : %d \n", argc); //main 함수가 받은 인자의 수(기본적으로 운영체제가 넣어줌)
printf("이 프로그램의 경로 : %s \n", argv[0]); //main 함수가 받은 받은 인자들
return 0;
}
cmd창을 키고 실행 시켜야 제대로된 결과를 볼수가 있다.
배열을 정할 때 그 크기는 언제나 컴파일 시간에 확정되어야 한다.
이렇게 되면 쓸데없이 큰 수를 넣는 경우가 많아서 낭비가 생긴다 이를 줄이기 위해서 필요한 만큼만 쓸 수 있도록 동적할당을 사용한다.
#include <stdlib.h> //이 라이브러리에 정의되어 있다.
memory allocation의 약자
arr = (int *)malloc(sizeof(int) * arr_size)
인자로 전달된 크기의 바이트 수 만큼 메모리 공간을 만든다
int형 크기를 알고 싶으면(int의 크기) * (arr_size)를 해주면 된다.
리턴형은 (void*) 형이라서 앞에 (int*) 이런식으로 형변환이 필요하다.
다 쓰고 메모리에 돌려주는 역할
free를 제대로 안하면 메모리 누수가 생긴다.
해제 순서는 할당하는 순서의 반대
int main()
{
int arr_size;
int* arr;
int sum = 0;
printf("학생의 수는? :");
scanf("%d", &arr_size);
arr = (int*)malloc(sizeof(int) * arr_size);
for (int i = 0; i < arr_size; i++)
{
printf("학생 %d 의 점수 : ", i);
scanf("%d", &arr[i]);
sum += arr[i];
}
printf("전체 학생의 평균 점수 : %d \n", sum / arr_size);
free(arr);
}
maloc함수는 힙을 사용해서 자유롭게 할당하거나 해제할 수 있다.
2차원 배열 동적할당 2가지 방법
1. 포인터 배열을 사용해서 2차원 배열처럼 동작하는 배열을 만든다.
2. 실제로 2차원 배열 크기의 메모리 할당 뒤 2차원 배열 포인터로 참조한다.
int main()
{
int i;
int x, y;
int** arr;
printf("arr[x][y] 만들기\n");
scanf("%d %d", &x, &y);
arr = (int**)malloc(sizeof(int*) * x);
for (i = 0; i < x; i++)
{
arr[i] = (int*)malloc(sizeof(int) * y);
}
printf("생성완료!");
for (i = 0; i < x; i++)
{
free(arr[i]);
}
free(arr);
return 0;
}
인자는 int arry(int **arry) 이런식으로 넘겨준다. 만든 배열은 2차원으로 보이긴 하지만 실제론 1차원 배열들이다.
void get_average(int** student_Score, int numSubject, int numStudent);
int main()
{
int i;
int subject, student;
int** student_score;
printf("과목의 수 : ");
scanf("%d", &subject);
printf("학생의 수 : ");
scanf("%d", &student);
student_score = (int**)malloc(sizeof(int*) * subject);
for (int i = 0; i < subject; i++)
{
student_score[i] = (int*)malloc(sizeof(int) * student);
}
for (int i = 0; i < subject; i++)
{
printf("과목 %d 점수 ----------\n", i);
for (int j = 0; j < student; j++)
{
printf("학생 %d 점수 입력 : ", j);
scanf("%d", &student_score[i][j]);
}
}
get_average(student_score, subject, student);
for (int i = 0; i < subject; i++)
{
free(student_score[i]);
}
free(student_score);
return 0;
}
void get_average(int** student_Score, int numSubject, int numStudent)
{
int sum = 0;
for (int i = 0; i < numSubject; i++)
{
sum = 0;
for (int j = 0; j < numStudent; j++)
{
sum += student_Score[i][j];
}
printf("과목 %d 평균 점수 : %d\n", i, sum / numStudent);
}
}
get_average에서 이차원배열 넘어가는 모양확인
기존 vs컴파일러에 안돌아가기 때문에 clang이라는 컴파일러를 설치하고 설정해줘야한다.
기본 사용법
Print_arr(int width, int(*arr)[width], int height);
int main() {
int width, height;
printf("배열 행 크기 : ");
scanf("%d", &height);
printf("배열 열 크기 : ");
scanf("%d", &width);
int(*arr)[width] = (int(*)[width])malloc(height * width * sizeof(int)); //width에 실제 배열의 열이 들어간 후 정의해야함
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int data;
scanf("%d", &data);
arr[i][j] = data;
}
}
Print_arr(width, arr, height);
free(arr);
}
Print_arr(int width, int (*arr)[width], int height) //width를 알도록 먼저 적어준다
{
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
앞에서 구현한 과목 학생의 성적 입력과 평균을 2번 방식으로 구현
void input_score(int student, int subject, int(*score)[student]);
void avg_score(int student, int subject, int(*score)[student]);
int main()
{
int subject, student;
printf("과목의 수를 입력해주세요: ");
scanf("%d", &subject);
printf("학생의 수를 입력해주세요: ");
scanf("%d", &student);
int (*student_score)[student];
student_score= (int(*)[student])malloc(sizeof(int) * subject * student);
input_score(student, subject, student_score);
avg_score(student, subject, student_score);
free(student_score);
return 0;
}
void input_score(int student, int subject, int(*score)[student])
{
for (int i = 0; i < subject; i++)
{
printf("%d 번째 과목\n", i);
for (int j = 0; j < student; j++)
{
printf("%d 번째 학생의 점수: ", j);
scanf("%d", &score[i][j]);
}
}
}
void avg_score(int student, int subject, int(*score)[student])
{
int sum = 0;
for (int i = 0; i < subject; i++)
{
sum = 0;
printf("%d 번째 과목의 평균 :", i);
for (int j = 0; j < student; j++)
{
sum += score[i][j];
}
printf("%d\n", sum / student);
}
}
int main()
{
int* p;
int p_size;
printf("크기를 입력해주세요: ");
scanf("%d", &p_size);
p = (int*)malloc(sizeof(int) * p_size);
for (int i = 0; i < p_size; i++)
{
p[i] = i;
}
add_size(&p, &p_size);
for (int i = 0; i < p_size; i++)
{
printf("%d ", p[i]);
}
free(p);
return 0;
}
int add_size(int** p, int *p_size) //포인터의 값을 바꾸기 위해서는 이중포인터를 사용해야한다
{
int* p2, add_size;
printf("늘릴 크기를 입력해주세요: ");
scanf("%d", &add_size);
int newsize = *p_size + add_size;
p2 = (int*)malloc(sizeof(int) * newsize);
for (int i = 0; i < *p_size; i++)
{
p2[i] = (*p)[i];
}
for (int i = *p_size; i < newsize; i++)
{
p2[i] = i;
}
free(*p);
*p = p2;
*p_size += add_size;
}
이중포인터의 역할, size를 어떻게 증가시키는지 사용방법 확인
편하게 바꾸려면 realloc를 사용하면된다.
int main()
{
int* arr;
int* arr2;
int arr_size;
scanf("%d", &arr_size);
arr = (int*)malloc(sizeof(int) * arr_size);
for (int i = 0; i < arr_size; i++)
{
arr[i] = i;
printf("%d ", arr[i]);
}
printf("\n");
arr = (int*)realloc(arr, 3 * sizeof(int));
for (int i = arr_size; i < arr_size + 3; i++)
{
arr[i] = i;
printf("%d ", arr[i]);
}
free(arr);
}
struct Something {
int a, b;
};
int main()
{
struct Something* arr;
int size, i;
scanf("%d", &size);
arr = (struct Something*)malloc(sizeof(struct Something) * size);
for (i = 0; i < size; i++)
{
printf("arr[%d].a :", i);
scanf("%d", &arr[i].a);
printf("arr[%d].b :", i);
scanf("%d", &arr[i].b);
}
for (i = 0; i < size; i++)
{
printf("arr[%d].a : %d, arr[%d].b : %d\n", i, arr[i].a, i, arr[i].b);
}
free(arr);
}
일반 변수와 똑같이 사용해주면 된다.