본문 바로가기

C언어/자료구조

2-1 장 배열(1)

1. int[5]형 배열에 값을 입력해 출력


# define N 5 //배열의 요소 개수 
int main()
{
 int a[N]; //배열의 선언
 for (int i = 0; i < N; i++) {
 printf("a[%d]:", i);
 scanf_s("%d", &a[i]);
}
puts("각 요소의 값");
for (int i = 0; i < N; i++) {
 printf("a[%d]=%d\n", i, a[i]);
}
return 0;
}

 

 

2. int형 배열을 초기화 하고 출력

 

int main() {
 int a[5] = { 1,2,3,4,5 };
 int na = sizeof(a) / sizeof(a[0]); //요소의 개수 
 printf("배열 a의 요소 개수는 %d입니다.\n", na);

 for (int i = 0; i < na; i++) {
  printf("a[%d]=%d\n", i, a[i]);
 }

 return 0;
}

 

 

3. 메모리할당과 동적 객체 생성하기 

 

3.1 c 언어의 메모리 구조 

 

 1) 데이터(Data)영역

  -  전역 변수와 정적(static)변수가 할당되는 영역

  - 프로그램이 시작하면 할당하고, 프로그램이 종료하면 메모리에서 해제함

 

 2) 스택(stack) 영역

  - 함수 호출시 생성되는 지역변수와 매개변수가 저장되는 영역

  - 함수호출이 완료되면 사라짐

 

 3) 힙(Heap) 영역

  - 필요에 따라 동적으로 메모리를 할당

  -  관리가 가능한 데이터 외에 다른 형태의 데이터를 관리하기 위한 빈공간

  - 동적할당(dynamic allocaiton)을 통해 생성된 동적 변수 (dynamic variables)를 관리하기 위한 영역

  - malloc, calloc 함수 사용

 

 3.2 calloc 함수 

 

- 크기가 size인 자료가 nmemb개만큼 들어갈 메모리를 할당. 할당한 메모리 영역은 모든 비트가 0으로 초기화됨

- 형식 : void *calloc(size_tnmemb, size_t size);

- 반환값 : 메모리 할당에 성공하면 할당한 영역의 첫 번째 포인터를 반환하고, 실패하면 NULL 포인터를 반환함

 

3.3 malloc 함수 

 

- 크기가 size인 메모리를 할당. 할당된 메모리값은 정의되지 않음

- 형식: void *malloc(size_t size);

- 반환값: 메모리 할당에 성공하면 할당한 영역의 첫 번째 포인터를 반환하고, 실패하면 NULL 포인터를 반환함

 

3.4 free 함수 

 

 - ptr이 가리키는 메모리를 해제하여 이후에 다시할당 할 수 있도록 한다.

 - 형식: void free(void *ptr);

 -반환값: 없음

 

- 단일한 int형 객체 생성

int main()
{
  int* x;
  x = (int*)calloc(1, sizeof(int)); //int형 포인터에 메모리 할당
  if (x == NULL) {
    puts("메모리 할당에 실패했습니다");
}
 else {
   *x = 57;
    printf("*x=%d\n", *x);
  free(x); //int형 포인터에 할당한 메모리 해제 
}

return 0;

}

 

 

 - calloc 함수는 지정된(1*sizeof(int)바이트) 크기의 메모리를 힙 영역에 할당하고, 할당한 메모리의 첫 번째 주소를 반환

 

4. 배열을 동적으로 생성하기 

 

 -지료형이 int형이고, 요소개수가 na인 배열 생성

 

int main()
{
  int na; //배열 a의 요소개수
  printf("요소 개수:");
  scanf_s("%d", &na);
  int* a;
  a = (int*)calloc(na, sizeof(int)); //요소 개수가 na개인 int형 배열 생성

  if (a == NULL)
  {
     printf("메모리 확보에 실패했습니다");
  }
  else {
  printf("%d개의 정수를 입력하세요\n", na);
  for (int i = 0; i < na; i++) {
   printf("a[%d]:", i);
   scanf_s("%d", &a[i]);
  }
  printf("각 요솟값은 아래와 같습니다.\n");
  for (int i = 0; i < na; i++)
    printf("a[%d]=%d\n", i, a[i]);
  free(a);
  }
  return 0;
}

 

 

4.1 포인터와 배열

 

 - int *p; -> p는 int형 객체를 가리키는 포인터 

   double *q; -> q는 double형 객체를 가리키는 포인터 

 

 -p=&n

  -> 포인터 p가 객체 n을 가리키기 위해서는 n의 주소를 p에 대입

 

 -주소연산자 &

 -> 피연산자의 주소를 가져옴

 

 -배열 이름 = 그 배열의 첫 번째 요소에 대한 포인터 

   -> a에 들어있는 값 = &a[0] (a[0]의 주소)

   -> 포인터 p가 배열의 요소 e를 가리킬 때

     요소 e의 i개 만큼 뒤쪽의 요소를 나타내는 *(p+i)는 p[i]로 표기 

     요소 e의 i개 만큼 앞쪽의 요소를 나타내는 *(p-i)는 p[-i]로 표기 

 

5. 배열 요소의 최댓값 구하기 

 

 - 최댓값 알고리즘 

  max=a[0];

  for(int i=1; i<n; i++)

     if(a[i]>max) max=a[i];

    

  - 주사(traverse)

   -> 배열의 요소를 하나씩 차례로 살펴보는 과정

   -> a[0]의 값을 max에 대입하고 for문에서 a[1]부터 마지막 요소 a[n-1]까지 차례로 살펴봄

   -> 배열의 모든 요소에 대해 주사를 완료한 시점의 배열 a의 최대 요솟값은 max에 대입

 

int maxof(const int a[], int n)
{
  int max = a[0];
  for (int i = 1; i < n; i++) {
    if (a[i] > max) max = a[i];
 }
 return max;
 }

int main()
{
  int number; //인원 - 배열 height의 요소 개수 
  printf("사람 수:");
  scanf_s("%d", &number);

  int *height;
  height = (int*)calloc(number, sizeof(int)); //자료형이 int형, 요소 개수가 number인 배열 height 생성
  printf("%d명의 키를 입력하세요\n",number);
  for (int i = 0; i < number; i++)
  {
    printf("height[%d]:", i);
    scanf_s("%d", &height[i]);
  }
  printf("최댓값은 %d입니다.", maxof(height, number)); //배열 height와 그 요소 개수 number를 maxof 함수에 전달 
  free(height);
}

 

5.1 함수의 매개변수로 배열 사용(뭔소린지 정확히 모르겠음,, 알듯 말듯)

 

 - int maxof(const int a[], int n);

  -> 매개변수 선언에서 []는 배열이 아니라 포인터를 선언하는 것과 같음

  -> const int *a로 해석

 

-const는 함수에서 그 인수가 가리키는 배열의 요솟값에 직접적으로 "쓰기"를 할 수 없게 만듬 (읽기는 가능)

 

- 함수 호출이 이루어졌을 때 호출된 함수가 받는 매개변수는 호출한 측이 부여한 실인숫값으로 초기화

 (const int *a=height -> height(&height[0])에서 매개변수 a가 초기화 -> 포인터 a는 height[0]의 주소를 가리킴

   => 포인터 a는 마치 배열 height인 것처럼 움직임)

 

 - 이떄 주고받는 인수(height)는 단순 포인터. 배열이 아님 -> 배열의 요소 개수를 알 수 없음

   => 배열의 요소 개수는 새로운 인수로 주고받아야함 그것이 바로 n

 

 

6. 난수로 배열의 요솟값 설정하기 

 

 - rand()함수 

  - 의사난수 (난수처럼 보이지만 일정한 규칙에 따라 생성되는 수)

  - 반환값 : 0이상 RAND_MAX이하 

  - seed (씨앗)를  사용하여 생성한 난수를 계산

 

- srand() 함수 

  - seed(씨앗)의 값을 변경하는 것

  - 일반적으로 srand함수에 현재 시간의 값을 주는 방법을 사용

    srand(time(NULL);

 

int maxof(const int a[], int n)
{
  int max = a[0];
  for (int i = 1; i < n; i++)
    if (a[i] > a[0]) max = a[i];
  return max;
}

int main()
{
  int number;
  printf("사람 수 :"); //배열 height의 요소 개수 
  scanf_s("%d", &number);
  int* height;
  height = (int*)calloc(number, sizeof(int)); //요소 개수가 number인 배열을 생성
  srand(time(NULL));
  for (int i = 0; i < number; i++) {
    height[i] = 100 + rand() % 90;
    printf("height[%d]=%d\n", i, height[i]);
  }
  printf("최댓값은 %d입니다.", maxof(height, number));
  free(height);

return 0;
}

 

'C언어 > 자료구조' 카테고리의 다른 글

3-2장 선형 검색  (0) 2023.07.25
3-1장 검색 알고리즘이란?  (0) 2023.07.25
2-2 구조체란?  (0) 2023.07.24
2-1장 배열(2)  (0) 2023.07.24
1장 기본 알고리즘  (0) 2023.04.06