[TIL] [2023.05.06] 백준 문제풀이 & C언어 개념공부

Pyotato·2023년 5월 6일
0

[TIL]

목록 보기
16/30
post-thumbnail

✍️오늘 공부한 내용

  • 백준 문제 풀이
  • C언어 개념 익히기: 포인터, struct (구조체), union, string, 함수(정의,선언,호출), 배열
  • 씹어먹는 C 추후 velog에 정리해서 올릴 예정

📋새로 배우게 된 내용

1 . list 를 sort해줄때 key로 함수를 제공하면 리스트의 각 아이템에 한번씩 적용하면서 sort한다.

 arr.sort(key=lambda x: (x[1], x[2]))
# If a key function is given, 
# apply it once to each list item and sort them, 
# ascending or descending, 
# according to their function values.
  • 오류 원인들
    • 보호된 메모리에 접근 할때
    • 읽기 권한이 없는 프로세스가 읽거나 쓰려고 할 때
    • 할당된 메모리 이외 메모리에 접근할 때
  • 프로그래밍 경우 발생 예
    • pointer로 할당되지 않거나 잘못된 메모리로 접근한 경우
    • 할당된 것보다 많은 문자를 입력한 경우 (주로 포인터를 사용하다 발생)
    • 잘못된 자료형 형식 포맷 스트링을 사용할 경우
  • 내 코드

    #include <stdio.h>
    
    struct person{
        char gender;
        int age;
    };
    
    struct person man1;
    struct person* woman1;
    
    int main(){
        man1.gender='M';
        man1.age=21;
        woman1 ->gender=26;
        // woman1 ->age='F';
        printf("man1 is %dyears old and '%c'\n",man1.gender,man1.age);
        return 0;
    };
  • pointer로 할당되지 않거나 잘못된 메모리로 접근한 경우

  • 수정 : woman1포인터가 가르키는 게 있도록 (man1)

     int main(){
         man1.gender='M';
         man1.age=21;
         printf("man1 is %dyears old and %c\n",man1.age,man1.gender);
         //man1 is 21years old and M
         woman1=&man1;
         woman1 ->gender='F';
         woman1 ->age=26;
         printf("woman1 is %dyears old and %c\n",man1.age,man1.gender);
         //woman1 is 26years old and F
    
         return 0;
     };

    타입 에러

  • C에서의 string은 결국 포인터,배열이고 string을 출력하기 위해서는 헤더에 #include <string.h>를 추가해줘야한다!

  • 내 코드

     #include <stdio.h>
     #include <string.h>
     int main(){
     
         char s1[12]="Hello";
         char s2[12]="World";
         char s2_2[30]="WorldofCoding";
         char s3[12];
      /*s1문자열내에서 s2문자열이 처음 발견되는 포인터를 반환*/
         // printf("strstr(s2_2,s2) : %c\n",(char)*strstr(s2_2,s2)); //strstr(s2_2,s2) : W
         //printf("strstr(s2_2,s2) : %s\n",strstr(s2_2,s2)); //strstr(s2_2,s2) : WorldofCoding
         return 0;
     };
     
  1. C언어를 공부하면서 가장 새로웠던 점은 pointer의 개념인 거 같아서 printf를 통해 출력값이 어떻게 달라지는 지 봤다. 그래서 발견한 에러도 여기에 등장!
    • expression must have integral type : 아래처럼 코드를 썼을 떄 나타난 에러. 포인터끼리 더하려다보니 에러가 발생. 포인터끼리 더해주면 안되는 이유?==더한값이 32bit나 64bit체제 메모리 주소이상일 수도 있음!
    • 내 코드
#include <stdio.h>
int max(int num1,int num2){
    /*지역 변수 result*/
    int result;


    result=num1+num2;
    int* p_num1=&num1;
    int* p_num2=&num2;

    int p_r=*p_num1+*p_num2;
    // int* pr=&(p_num1+p_num2);
   
    printf("p_num1: %p\n",p_num1); //0x7ffd990078cc
    printf("p_num2: %p\n",p_num2); //p_num2: 0x7ffd990078c8
    printf("result:%d\n",result);//result:30
    printf("p_r: %d\n",p_r); //p_r: 30


    return result;
}

int main(){
    int a=10;
    int b=20;
    max(a,b);
    return 0;
};
 

🤯어려웠던 점

  1. heapq로 문제를 접근해야겠다는 생각이 바로바로 떠오르지 않았다.
  2. 포인터 개념도 처음 배우고, 주소값을 출력해올 때랑 값을 출력할 때랑, 가져오는 값의 자료형이 내가 생각한 거랑 달라서 컴파일이 안될 때가 있었다.
  3. 아직 해결중인데 extern으로 외부 함수에 접근하는 코드가 잘 안짜인다🤔

😸어려움을 해결한 방법

  1. 코드 풀이 : 주석 + 내 방식대로 조금씩 바꿔보기 +print해서 흐름 파악하기
import sys, heapq
input = sys.stdin.readline
n = int(input())
arr = [list(map(int,input().split())) for _ in range(n)]
lecture = [0 for _ in range(n+1)] #배정해줄 강의실
arr.sort(key=lambda x: (x[1], x[2]))# 강의 시간을 기준으로 정렬
room = []
def tmtbl(N):
    for i in range(1, N+1):
        # 강의의 종료시간과 강의실 번호 heap에 넣기
        heapq.heappush(room, i)
    minHeap = []
    for x in arr:
        # 힙에 값이 있고, 강의 시작 시간시간이 비교하고 있는 강의 종료시간보다 이르면 pop
        while minHeap and minHeap[0][0] <= x[1]:
            # 힙의 길이만큼의 인덱스를 강의실 번호로 지정하여 배열에 저장
            _, r = heapq.heappop(minHeap)
            heapq.heappush(room, r)
        r = heapq.heappop(room)
        heapq.heappush(minHeap, [x[2], r])
        lecture[x[0]] = r # minHeap으로 아직 배정되지 않은 강의실에 강의실 번호 배정
    return("\n".join(list(map(str,[max(lecture),*lecture[1:]]))))
print(tmtbl(n))
  1. 생각보다 에러메시지가 친절하기도하고, 구글링+디버깅 breakpoint지정을 잘해주면 찾기 용이해지는 것 같다.
  2. 조금만 현재 코드 에러를 수정해보고, 구글링해서 참고해야할듯..

🤔아쉬웠던 점

  • heapq 사용이 미숙해서 결과값을 예측하기보다는 일일히 print로 찍어봐야했다. heapq관련 개념정리를 다시 해야겠다.

😝느낀점

  • 왜 포인터끼리 더해주면 안돼?라는 생각이 들었는데, 찾아보니까 메모리가 저장되는 방식이 연속적인데 32비트 혹은 64비트 체제에서 이 범위를 초과한 덧셈결과가 나올 수 있어서라고 한다. 그래서 포인터끼리 빼준 값은 이 범위에 들어갈 수 있는데 (음수면?) 덧셈은 포인터가 어떤값이 나올지 모르므로 안된다고 결론이 났다.
  • 이런 점에서 씹어먹는 C에서 운영체제와 C는 밀접한 관계라고 하는데, 그렇기때문에 운영체제 공부와 기본기 다지기에 충실해야한다고 생각이 들었다.
  • 즉, c언어를 잘하려면 운영체제에 대한 공부도 필수가 아닐까 생각이 든다.

👊다짐

  • 운영체제 & computer programs 책도 조금씩이라도 읽도록 해야겠다.
  • 내일은 computer programs 3장 다 읽어보고 씹어먹는 C한번 쭉 읽고 정리하는 시간을 가져야겠다.
  • c언어 사용이 아직 미숙해서 자료구조를 작접 구현하는 건 무리겠지만, 코드를 보면서 주석을 남겨 이해하고 나만의 코드로 바꿔보는 연습을 하도록 해야겠다.

🚀오늘의 한줄평

  • C 오류메세지는 은근히 친절(?)한 거 같다.
profile
https://pyotato-dev.tistory.com/ 로 이사중 🚚💨🚛💨🚚💨

0개의 댓글