게시글
질문&답변
2024.04.20
linear independence이라면 왜 one-to-one인가요?
Matrix A의 Column들이 linearly independent 하다는 것은 if and only if A가 one-to-one mapping입니다. 증명은 여러 가지로 많이 소개되어있으니 직접 찾아보시면 되겠습니다. 제가 이 동치를 직관적으로 이해하는 방법은 아래와 같습니다. 우선 one-to-one의 linear mapping에서의 직관적 의미부터 되새겨봅시다. A가 one-to-one mapping이라는 것은 Ax = b에서 서로 다른 x가 각각 서로 다른 b로 mapping 된다는 뜻입니다. 여기서 Column들의 linear independence 의 linear mapping 에서의 의미를 되새겨봅시다. Column들의 linear independence는 A의 Column들 중 어느것도 서로 다른 column들의 linear combination으로 표현될 수 없다는 뜻입니다. 반대로, column 들이 linearly dependent하다면, 어떤 column은 다른 column들의 linear combination으로 표현됩니다. 여기서, i번째 column이 vector x의 i번째 element 를 mapping 하는 것임을 상기해보면 (1.8 강의 standard matrix 부분을 보시면 됩니다), linearly dependent 하다면, vector x의 '어떤 element k'가 mapping되는 결과는 vector x의 다른 element가 mapping 된 것의 조합으로 표현됩니다. 따라서, element k는 어떻게 결정되어도 상관없는 free variable이게 됩니다. 따라서, one-to-one이지 않습니다. 이의 대우로, one-to-one이면 linearly independent하게 됩니다. 조금 rough하게 적어서 엄밀한 설명은 아닙니다만, linear independence와 one-to-one이 linear map에서 어떤 관계가 있는지 이해하시는데에 도움이 되었으면 합니다 :)
- 0
- 2
- 412
질문&답변
2020.09.12
1.6 {u,v,w} in R^3 질문드립니다
아 생각보다 간단한 거였네요 ㅎㅎ 이해됐습니다. 감사합니다!
- 1
- 2
- 200
질문&답변
2020.08.06
while (scanf(
부족한 제 설명이 도움이 됐다니 다행입니다 :)
- 2
- 8
- 1K
질문&답변
2020.08.05
질문있습니다!
IDE마다 달라질 수 있겠으나, 보통 주소의 크기는 32bit 환경에서 4byte, 64bit 환경에서 8byte입니다. 64bit로 실행하신게 아닐까 추측해봅니다 :)
- 1
- 1
- 352
질문&답변
2020.08.05
while (scanf(
**오류 발견 시 지적 부탁드립니다.** 조금 까다로운 부분인데, 최대한 이해되도록 설명해보겠습니다. scanf("%[^\n]%*c", input) 에서 빈 엔터를 입력하면 %[^\n]에 의해 scanf는 아무것도 읽어들이지 않습니다. \n 전까지 읽어야하는데, 첫 문자가 \n이니 작동하지 않는거죠. 따라서, while 문 검사에서 계속 빈 엔터를 마주치니, %[^\n]에 의해 scanf가 아무것도 읽어들이지 않고, 그렇기에 애초에 %*c 작동으로 이어지지 않는 겁니다. 그렇다면, %*c는 도대체 왜 필요할까? 아래의 단순한 코드를 실행해봅시다. #define _CRT_SECURE_NO_WARNINGS #include int main() { char input1[10]; scanf("%[^\n]", input1); printf("%s checked", input1); } 분명 이 코드에서는 scnaf 안에 %*c가 없습니다. 그러나 %*c가 있는 코드와 동일하게 동작합니다. scanf 안을 바꿔가면서 실행해보세요 그런데 아래의 코드를 실행해보시면, %*c가 있고 없음에 따라 결과가 달라집니다 #define _CRT_SECURE_NO_WARNINGS #include int main() { char input1[10]; char input2[10]; scanf("%[^\n]", input1); scanf("%[^\n]", input2); printf("%s checked", input1); printf("%s checked", input2); } 이 코드에서 abc를 입력하면 아래와 같은 결과가 나옵니다 (사진) 이때 디버거로 주소를 확인해보면 아래와 같은 상태가 됩니다 (사진) 즉, input1을 받고나서 버퍼에 남은 \n 때문에 input2를 받는 scanf가 제대로 실행되지 않고 출력시에 input1은 정상적으로 출력되지만 input2를 출력하려고 하니 문자열 끝의 \0 이 없고 쓰레기 값을 계속 출력하다가 input1의 메모리까지 침범해서 input1 끝의 \0을 만나서야 printf가 끝나는 모양새입니다 이 코드에서 원래와 같이 %[^\n]%*c 를 사용하면, input1 input2 모두 정상적으로 입력받을 수 있습니다. 따라서 정리하자면 이렇습니다 %*c는 버퍼에 남아있는 \n을 비워주는 역할이 맞다. 정확히는, 마지막 문자인 \n을 버퍼로부터 읽어들이지만, 없는셈 치고 문자열에는 입력해주지 않는 것입니다. 그러나, [Enter]만 입력했을 경우 &[^\n]에 의해 scanf가 애초에 읽어들이지 않으므로 %*c가 작동하지 않았다는 것입니다. -답변이 도움이 되셨다면 좋아요를 눌러주세요!-
- 2
- 8
- 1K
질문&답변
2020.08.05
count함수에서 버퍼비우기 필요한 이유?
**오류 발견 시 지적 부탁드립니다.** 넵 먼저 첫번째 질문에 답변드리겠습니다. 제가 홍정모 교수님이 프로그램을 설계하신 의도를 다 알 수는 없지만, 이 프로그램의 경우 c를 입력하면 count라는 기능이 동작하도록 되어있습니다. count를 동작시키기 위해 get_integer 라는 함수를 사용해서 integer 하나를 입력받는 것이구요. get_integer 내부에서는 정수가 입력된 게 맞는지 확인하고, 맞다면 return 하는 식으로 동작하는 거죠. (count 기능의 내부기능으로 get_integer 기능) 이때 제가 드린 2번 질문처럼 '만약에 get_integer 안의 scanf 에서 input이 정상적으로 입력됐으나, 버퍼에 남는 값이 생긴다면?' 이라는 가정을 해봅시다. 이 가정에 맞는 input 값은 "123 k" 와 같은 input일 것입니다. "123 k" 를 입력하면 scanf가 공백문자 전까지 입력을 받아 123이 정상적으로 입력되지만, " k"가 버퍼에 남게 됩니다. 따라서 count 함수는 버퍼에 남았을지 모를 값을 비워줘야 합니다 (물론 get_integer 에서 input을 return 하기전에 버퍼를 비워줘도 문제 없겠습니다) count 함수가 끝나면 다시 사용자의 선택 (a, b, c, q) 을 입력받을텐데, 버퍼에 값이 남으면 오동작이 발생하게 되니까요. while (getchar() != '\n') continue; 를 주석처리 해놓고 "123 k" 와 같은 값을 입력해보시면 어떤 식으로 작동하는지가 이해되실 거라고 생각합니다 두번째 질문에 대한 답은 생각하신 대로가 맞습니다. 그러나, getchar()의 버퍼와 scanf 버퍼가 따로 있는 것이 아닙니다. 입력(키보드)에 대한 버퍼가 있고, 입력시에 그 버퍼에서 값을 임시로 받아두었다가 한번에 옮기는 것입니다. 따라서 getchar 를 이용해 입출력 버퍼를 비우는 게 가능한 것입니다. (추가 설명) 참고 : https://jhi93.github.io/category/os/2019-11-25-operatingsystem-02-1/ 참고로 올려드린 사이트의 첫번째 그림을 보시면, 키보드와 마우스에 local buffer가 있는 모습을 보실 수 있습니다 이 부분은 저 역시 공부중인 부분이라 더 정확하게 설명드리기가 조금 어렵네요 -답변이 도움이 되셨다면 좋아요를 눌러주세요!-
- 0
- 3
- 406
질문&답변
2020.08.04
while (scanf(
**오류 발견 시 지적 부탁드립니다.** 넵 말씀하신대로 버퍼 때문이 맞습니다. 홍정모 교수님께서 왜 코드를 저렇게 쓰셨는지는 모르겠으나, 아마 엔터만 들어올 경우를 가정하지 않고 작성하신 것 아닐까요? scanf가 작동하는 방식을 생각해봅시다. "%[^\n]%*c"에 따라 \n을 만날때 까지([^\n]) 읽어들이고, 마지막의 문자는 무시(*c)합니다. 이때 [Enter]만 입력하면? 먼저 버퍼에 \n이 쓰여질 겁니다. 동시에, scanf가 공백문자를 만났으므로 작동하기 시작합니다. 이때 scanf는 format specifier 에 따라 \n 만나기 전까지 읽고, 마지막 문자를 무시합니다. 이때 \n 만나기 전까지 읽는다는 것은, \n을 읽는다는 것일까요, 버퍼에 남겨두는 것일까요? #define _CRT_SECURE_NO_WARNINGS #include int main() { char input[10]; char ch; scanf("%[^'k']%*c", input); printf("%s\n", input); ch = getchar(); printf("%c\n", ch); } 이런 코드를 예시로 실행해봅니다. 입력에 abck를 넣으면, abc가 먼저 출력되고, 한줄을 띄운 후 k가 출력됩니다 즉, 버퍼에는 k가 남습니다. k 대신 \n 으로 실행해도 마찬가지입니다. 원래 코드로 돌아가, while 조건 검사 이후 printf가 실행되고, 다시 while문의 조건 검사를 하는데, 위와 똑같은 일이 반복됩니다. 버퍼에 있는 건 \n 뿐인데, [^\n]으로 인해 \n을 버퍼에 남기고 읽으니 반환값은 계속 0이고 무한루프를 돌 수 밖에 없습니다 해결책은, while 문안에 버퍼를 지우는 코드를 추가하면 됩니다. -답변이 도움이 되셨다면 좋아요를 눌러주세요!-
- 2
- 8
- 1K
질문&답변
2020.08.04
count함수에서 버퍼비우기 필요한 이유?
1. scanf 는 공백을 기준으로 나눠서 입력받습니다. 따라서, 버퍼에 남는 값이 생길 수 있습니다 2. '만약에 get_integer 안의 scanf 에서 input이 정상적으로 입력됐으나, 버퍼에 남는 값이 생긴다면?' 이라는 가정을 해봅시다. 어떤 입력을 넣으면 위의 가정대로 진행될까요? 3. 2에서 버퍼에 값이 남은채로 count 에, while (getchar() != '\n') continue; 가 없다면? 해당 코드만 주석처리 해놓고 2에서 찾은 입력값을 넣어보세요. 못 찾으시겠으면 다시 질문 주시면 알려드리겠습니다 :) -답변이 도움이 되셨다면 좋아요를 눌러주세요!-
- 0
- 3
- 406
질문&답변
2020.08.04
형식지정자 크기와 자료형에 대한 질문입니다.
**100% 정확한 설명이 아닐 수 있습니다. 오류 발견 시 지적 부탁드립니다.** 먼저 format specifier 는 변수를 어떻게 읽어낼 것인지 알려주는 parameter 입니다. 즉, %lld는 char c를 long long int 처럼 읽어내겠다는 뜻이지, char c 가 long long int 가 되는 것이 아닙니다. 따라서 위의 코드에서 c를 long long int 로 캐스팅 하고 %lld로 읽어내면 해당 문제가 사라집니다 아래의 내용은 조금 더 심화된 설명입니다 ( 참고한 글 https://operatingsystems.tistory.com/entry/Kernel-printf-%ED%95%A8%EC%88%98 ) 뒷부분 함수, 포인터 등의 강의를 듣고 다시 읽으시면 조금 더 이해되실 것 같습니다 (사진) 첫 줄만 실행했을 때의 결과값입니다 (사진) 디버거에서 해당되는 메모리를 읽었을 때의 캡쳐 사진입니다 이 내용을 이해하시려면 스택에 대한 이해가 필요한데 현재 메모리의 스택에 c, s ui, l, ll 이 쌓여있습니다. c는 char 자료형으로 1 byte를 사용하고, 16진수로 표현된 c의 아스키 코드 값은 41입니다. 그리고 문제의 %lld의 쓰레기값이 나오는 부분이 별표 친 부분입니다 상단에 첨부해드린 제 결과값을 보시면, %lld로 출력했을 때의 십진수 값은 14,094,884,369,596,481입니다 이를 16진수로 바꾸면 0032 1339 0000 0041 이고, 그게 바로 별표 친 부분의 값입니다 그럼 왜 이러한 문제가 발생하느냐 여기서부터는 사실과 추측이 섞인 답변이니, 참고하시고 받아들이시기 바랍니다 별표친 부분의 우측에 ?가 가득한 창을 보시면, A가 여러 번 적혀있는 것을 알 수 있습니다. 이는 c의 값인 65로서, printf가 호출되며 함께 호출된 것입니다. 자세한 이유는 모르겠으나, A... 5번 반복되는 것으로 보아, char, short 할 것 없이 모두 4byte 씩 공간을 차지하고 있습니다 (printf 에서 스택에 주소값을 올리는 것과, x64에서는 A.......으로 8byte를 갖는 것으로 추측해보면, 주소의 크기만큼 공간을 차지하는 것으로 보입니다) 이때 마지막에 %lld로 읽어들이면, 실제 변수가 갖는 값보다 더 큰 공간을 읽어들이게 됩니다. 이때 garbage value 가 출력되는 것입니다. (printf 내에서 %lld를 맨 앞으로 옮겨보면, 맨 마지막의 format specifier 에서도 데이터가 밀리는 오류가 발생함을 알 수 있습니다. 이때의 값은 10진수로 279,172,874,305이 출력되는데 16진수 값으로는 A가 존재하는 4byte 공간 두개를 붙인 0000 0041 0000 0041 임을 알 수 있습니다.) 정리하자면, 이런 문제가 발생하는 것은 %lld가 변수를 읽어내는 방식에 불과하기 때문입니다. 실제 변수가 차지하는 공간보다 큰 공간을 읽어들이기 때문에 문제가 발생합니다. -답변이 도움이 되셨다면 좋아요를 눌러주세요!-
- 0
- 1
- 381
질문&답변
2020.08.04
while (scanf(
엔터를 입력했을 때 scanf("%[^\n]%*c", input) 에서 반환값이 어떻게 될까요? 그리고 그 반환값에 따른 while문의 조건상태는?
- 2
- 8
- 1K