2021.03.05.금 구조체 선언과 멤버 사용 ✔ 구조체는 사용자가 임의로 정의한 자료형이라고 볼 수 있다. ✔ 구조체를 선언하면 새로운 자료형이 만들어지고, 그 이후부터는 구조체 변수를 만들어 사용할 수 있다. struct student{ int num; double grade; }; ✔ 구조체는 struct 예약어를 사용해 선언한다. ✔ 구조체의 이름은 성격에 맞는 적절한 이름을 붙이고, 중괄호 내부 블록 안에 필요한 멤버를 나열한다. ✔ 멤버 선언은 구조체를 구성하는 자료형 종류와 이름을 컴파일러에게 알리는 역할을 한다. ✔ 선언 형태는 변수와 유사하나, 메모리 저장 공간을 할당받지 않는다는 차이점이 있다. ✔ 그리고 마지막으로 중괄호로 블록을 닫아준 뒤에는 반드시 세미콜론을 붙여야 한다. #in..
2021.03.04.목 동적 할당을 사용한 문자열 처리 ✔ 동적 할당은 프로그램의 효율을 높이기 위한 방법 중 하나이다. ✔ 입력할 문자열의 길이를 알 수 없는 경우, 저장 공간을 넉넉하게 선언하는데, 이는 저장 공간의 낭비를 초래한다. ✔ 동적 할당을 사용하게 되면 입력 문자열의 길이에 맞게 저장 공간을 사용할 수 있다. #include #include #include int main(void){ char temp[80]; // 임시 char 배열 char* str[3]; // 동적 할당 영역을 연결할 포인터 배열 for(int i = 0; i < 3; i++){ printf("문자열을 입력하세요 : "); gets(temp); // 문자열 입력 str[i] = (char*)malloc(strlen(t..
2021.03.04.목 malloc, free 함수 ✔ malloc() 함수를 사용해서 동적 메모리를 할당받고, free() 함수를 사용해서 반환한다. ✔ malloc() 함수와 free() 함수는 헤더 파일에 포함되어 있으니 전처리가 필요하다. (포인터 형변환) malloc (메모리크기); int * p = (int *) malloc (sizeof(int)); ✔ malloc() 함수는 void 포인터를 반환하므로, 포인터 변수에 저장할 때에는 필요한 자료형으로 형변환해야한다. ✔ 필요한 만큼 공간을 할당받을 수 있는데, 이는 byte기준이며, sizeof() 연산자를 사용해 크기를 계산해 넣어주자. ✔ 그렇게 하면 컴파일러나 운영체제에 따라 int형 변수의 크기가 다르더라도 수정할 필요가 없다. in..
2021.03.03.수 함수 포인터 ✔ 함수를 정의하고 프로그램을 컴파일하면, 함수도 메모리 공간에 올라간다. ✔ 메모리에 올려진 함수를 실행하기 위해서는 그 위치를 알아야 한다. ✔ 배열과 마찬가지로 함수도 함수의 이름이 곧 메모리 주소를 의미한다. ✔ 그리고 함수가 호출되면 함수가 저장된 주소로 이동한다. ✔ 함수의 주소도 포인터에 저장할 수 있고, 포인터를 사용해 함수를 호출할 수도 있다. int 함수명 (int, int); //함수 선언 int 함수포인터명 (int, int); //함수 포인터 선언 ✔ 주소를 저장할 함수 포인터는 주소가 가리키는 것과 동일한 형태를 가리키도록 선언해야 한다. ✔ 함수의 형태는 매개변수의 개수와 자료형, 그리고 반환 값의 자료형으로 정의한다. ✔ 함수의 형태는 함수..
2021.03.03.수 포인터 배열과 배열 포인터 int *p_arr[3]; ✔ 포인터 배열 : 배열 요소로 포인터 변수를 가지는 배열을 의미. 즉, 포인터 변수를 저장할 수 있는 배열을 의미. int (*arr_p)[3]; ✔ 배열 포인터 : 배열 포인터란 배열을 가리킬 수 있는 포인터를 의미. ✔ 선언은 위와 같이 배열명 앞에 별(*)을 붙여 포인터임을 표시하고 괄호로 묶어 준다. ✔ 괄호 없이 선언하게 되면 포인터 배열로 선언되므로 주의하자. int arr[2][3] = { {10, 20, 30}, {40, 50, 60} }; int (*arr_p)[3] = arr; // 배열 포인터의 선언 printf("%d\n", arr[1][1]); // 배열 이름으로 참조 50 printf("%d\n", a..
2021.03.03.수 배열 요소의 주소와 배열의 주소 int arr[5]; ✔ 배열명 arr 자체가 주소로 쓰일 때에는 첫 번째 요소를 가리키므로 arr+1 은 4byte 증가해 다음 요소를 가리킨다. ✔ 반면 배열의 주소인 &arr는 배열의 전체를 가리키므로, &arr+1 은 요소의 개수 x 4byte 증가한다. ✔ 배열의 주소에 정수를 더하는 연산은 가능하지만 ✔ 배열에 할당된 메모리 영역을 벗어날 수 있으므로 특별한 경우가 아니라면 사용하지 않는다. ✔ 실행결과를 확인하면 배열의 첫 번째 요소의 주소를 가지는 배열의 주소와 주소 연산자&를 사용한 배열의 주소는 동일하다. ✔ 하지만 +1 연산의 결과는 다른 것을 확인할 수 있다. ✔ 첫 번째 주소를 가지는 배열명의 주소는 +1 연산하게 되면, 1x..
2021.03.03.수 이중 포인터의 활용 : 포인터 값을 바꾸는 함수(swap_prt)의 매개변수 void swap_ptr(char** ppa, char** ppb){ char *temp = *ppa; *ppa = *ppb; *ppb = temp; } ✔ 이중 포인터는 포인터의 값을 바꾸는 함수의 매개변수에 사용된다. ✔ 2개의 포인터 변수에 문자열 상수의 주소가 각각 저장되어 있는 경우 이중 포인터를 활용해 ✔ 포인터 변수가 가르키는 문자열 상수의 주소를 바꾸어줄 수 있다. ✔ 변수의 swap함수를 이중 포인터를 사용해 구현해보자. 이중 포인터의 활용 : 포인터 배열을 매개변수로 받는 함수 //포인터변수를 저장하는 이중 포인터와 int형 변수를 매개변수로 받는 함수 void print_str(char..
2021.03.03.수 이중 포인터 ✔ 포인터도 저장공간을 갖는 하나의 변수이므로, 주소 연산을 사용해 포인터의 주소를 구할 수 있다. ✔ 그리고 포인터의 주소를 저장하는 포인터는 이중 포인터라고 말한다. ✔ 포인터를 저장하는 이중 포인터에 간접 참조 연산을 사용하면, 저장된 포인터의 주소를 반환한다. ✔ 포인터의 주소를 저장한 이중 포인터에 간접 참조 연산을 수행하면, 가리키는 대상인 포인터를 사용할 수 있다. ✔ 포인터 변수의 배열은 포인터를 요소로 갖는 배열. 간접 참조 연산을 수행하면 저장된 주소를 반환한다. ✔ 이중 포인터는 포인터의 주소를 저장. 간접 참조 연산을 수행하면 저장된 포인터를 사용해 대상을 가리킬 수 있다. 이중 포인터의 선언 int **ppi; ✔ 이중 포인터를 선언할 때에는 *..
2021.03.02.수 포인터 배열 복습 예제 ▼▼▼ 출력 코드는 더보기 참고 😎 더보기 #include int main(void) { int arr1[3] = { 1, 2, 3 }; int arr2[3] = { 4, 5, 6 }; int *parr[2] = { arr1, arr2 }; printf("\t\t[0]\t[1]\t[2]\n"); printf("arr1\t\t%d\t%d\t%d\n",arr1[0], arr1[1], arr1[2]); printf("arr2\t\t%d\t%d\t%d\n\n",arr2[0], arr2[1], arr2[2]); printf("\t\t [0]\t [1]\t [2]\n"); printf("arr1\t\t%d\t%d\t%d\n",arr1, &arr1[1], &arr1[2]..
2021.03.02.화 3차원 배열 ✔ 2차원 배열은 1차원 배열을 요소로 가졌다면, 3차원 배열은 2차원 배열을 요소로 가진다. ✔ 3차원 배열은 3개의 첨자를 사용하여 선언한다. int score[2][3][4]; ✔ 2차원 배열에서 각 행은 1차원 배열로서 2차원 배열을 구성하는 하나의 부분 배열이 된다. ✔ 3차원 배열에서 각 행은 2차원 배열로서 3차원 배열을 구성하는 하나의 부분 배열이 된다. ✔ 2차원 배열이 행과 열로 이루어져 있다면, 3차원 배열은 면과 행, 열으로 이루어져 있다. int classAscore[3][5]={ {90, 80, 70, 60, 50}, {50, 70, 60, 40, 80}, {70, 40, 20, 90, 70} }; int classBscore[3][5]={ {..