묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결홍정모의 따라하며 배우는 C언어
\t 간격 차이
#include <stdio.h> #include <stdlib.h> struct kid { char name[100]; int height; }; int compare(const void* first, const void* second) { if (((struct kid*)first)->height > ((struct kid*)second)->height) return 1; else if (((struct kid*)first)->height < ((struct kid*)second)->height) return -1; else return 0; } int main() { struct kid my_friends[] = { "Jack Jack", 40, "Geenie", 300, "Aladdin", 170, "Piona", 150 }; const int n = sizeof(my_friends) / sizeof(struct kid); qsort(my_friends, n, sizeof(struct kid), compare); for (int i = 0; i < n; i++) printf("%s \t%d\n", my_friends[i].name, my_friends[i].height); return 0; }위는 저의 코드입니다.강의 5분 45초를 보면 printf()함수에 \t를 통해서 간격을 조정해주는데 교수님의 경우 숫자가 같은 위치에서 시작하는데 저는 왜 40 혼자 멀리 떨어져있을까요? 또 \t를 검색해보면 Tab키와 같이 일정한 간격을 띄움라고 나와있는데 일정한 간격을 어디를 기준으로 띄우는 건가요?"Jack Jack"의 경우 공백 포함 9글자고"Geenie의 경우 6글자인데강의에서 "40", "300"은 같은 위치에서 시작함에 의문이 생깁니다.
-
미해결홍정모의 따라하며 배우는 C언어
디버그 >창>메모리가 안떠요
디버깅>일반에서 주소 수준 디버깅 사용을 선택했는데도 디버그 >창 > 메모리가 있어야 하는데 메모리가 안뜨는데 왜 이런 건가요?
-
미해결홍정모의 따라하며 배우는 C언어
9.15 쓰레기값 관련해서
제가 알기로 값을 따로 초기화 안할경우 무작위의 쓰레기값이 들어가는게 아니라, 그냥 16진수 cccccccc 가 들어가는걸로 알고 있습니다.
-
해결됨독하게 되새기는 C 프로그래밍
자료구조
연결리스트를 보면서 만든적은 있으나 머리속에서 참고자 없이 만든적은 없네요 구매는 했는데 자료구조 수업 듣고 와야겠네요. 혹시 수업이 따로 있을까요?
-
해결됨독하게 되새기는 C 프로그래밍
실습 중에 혹시 예외 발생하신 분들을 위해
Enter, Leave로 동기화 후 메인 쓰레드 루프 탈출을 위해q를 입력했을 때 간헐적으로 아래와 같은 에러가 발생하였습니다요거.. 선생님께 여쭤보려다가 문득 원인을 찾았습니다혹시 저와 같은 에러를 겪으신 분들을 위해 정리를 하자면 아래와 같습니다 메인 쓰레드 루프 탈출 까지는 정상적으로 수행됩니다다만, DeleteCriticalSection 함수 호출 후 return 코드를 호출하기 전 찰나의 순간에set 또는 reset 워커 쓰레드에서 EnterCriticalSection을 호출하여 예외가 발생합니다 즉, DeleteCriticalSection과 return의 코드 호출은원자적이지 않기 때문에 두 함수가 수행되는 중간에다른 워커 쓰레드에서 EnterCriticalSection 함수를 호출하는 경우인데요 이는, Delete돼서 존재하지 않는 임계영역에 Enter를 시도하기 때문입니다
-
미해결홍정모의 따라하며 배우는 C언어
11분 40초 프로그램에 저장
피피티에서 int i = 34567; 이 왜 10000111 | 00000111로 저장되는지 궁금합니다
-
미해결홍정모의 따라하며 배우는 C언어
visual studio code shell 설정
visual studio code 에서 Shell 검색을 하였을 때 다음과 같이 shell관련 항목이 나오지 않습니다.사전에 mingw도 설치하였고 path도 설정하였습니다. 해결 방법을 알고 싶습니다.
-
해결됨독하게 되새기는 C 프로그래밍
안녕하세요 선생님~ 몇 가지 여쭤볼 게 있습니다
항상 좋은 강의 감사합니다 ~!!두 가지 정도 여쭤볼 게 있습니다 실시간 감시 엔진File System과 Driver 사이 계층에 실시간 감시 엔진을 넣을 수 있는 공간이 있다고 하셨는데 그렇다면그런 엔진은 V3, 알약 같은 백신 프로그램에서 제공해주나요? 아니면 OS단에서 기본적으로 제공해주나요?만약 OS단에서 제공해준다면 감시 결과에 접근할 수 있는 인터페이스를 열어주고유저모드의 백신 프로그램이 그 인터페이스로 감시 결과를 가져오나요?삭제삭제 시 FAT에서 Delete 필드에 마킹되는 것은 이해하였습니다그런데 굳이 파일명의 첫 글자 까지도 다른 글자로 변경하는 이유는 무엇인가요?강의 잘 보고 있습니다 감사합니다 ~
-
미해결HAL, CubeMX, TrueSTUDIO를 이용한 STM32F4 무료 강좌
파일 생성이 되지 않습니다
강의 그대로 세팅 다 하고 난 후 강의처럼 OK버튼이 없어 오른쪽 상단의 GENERATE CODE를 눌렀습니다.이런 메세지 창이 뜨는데 어떻게 해야하나요??GENERATE CODE 버튼을 누르는게 아닌가요?
-
미해결홍정모의 따라하며 배우는 C언어
구조체의 복사에서 멤버가 문자열인경우
#include <stdio.h> #include <stdlib.h> struct data { int a; char str[20]; }; int main(void) { struct data data1 = { 1,"hello" }; struct data data2 = data1; printf("%s", data2.str); return 0; }강의 7:40를 보면 구조체 변수에 다른 구조체 변수를 대입하면 그 안의 값이 똑같이 복사가 가능한데,문자열도 복사가 가능한지 궁금해서 위처럼 실행시켜보니까 가능하네요. 이것은 마치data1.str = "hello";data2.str = data1.str;인 것 같은데.제가 알기론 문자열은 대입을 통해서 복사 하는 것이 불가능한 것으로 알고 있는 구조체에서는 가능한건가요?미흡한 질문 죄송합니다.
-
미해결HAL, CubeMX, TrueSTUDIO를 이용한 STM32F4 무료 강좌
파일이 없습니다.
소스 파일이 없어요
-
미해결HAL, CubeMX, TrueSTUDIO를 이용한 STM32F4 무료 강좌
사용 프로그램이 맞나요?
STM32f407ve를 검색했는데 아무것도 안떠요ㅠㅠㅠ
-
미해결홍정모의 따라하며 배우는 C언어
콘솔창에서 한글이 깨지는 이유
#include <stdio.h> #include <windows.h> int main(int argc, char* argv[]) { int ch; FILE* fr, * fw; //const UINT default_cp = GetConsoleOutputCP(); //printf("%u\n", default_cp); const char* in_filename = "원본.txt"; const char* out_filename = "사본.txt"; unsigned long count = 0; if ((fr = fopen(in_filename, "r")) == NULL) { printf("can't open %s\n", in_filename); exit(EXIT_FAILURE); } if ((fw = fopen(out_filename, "w")) == NULL) { printf("can't open %s\n", out_filename); exit(EXIT_FAILURE); } //SetConsoleOutputCP(CP_UTF8); while ((ch = fgetc(fr)) != EOF) { fputc(ch, stdout); fputc(ch, fw); count++; } fclose(fr); fclose(fw); //SetConsoleOutputCP(default_cp); printf("file %s has %lu characters\n", in_filename, count); printf("copied to %s\n", out_filename); printf("한글 출력 확인"); return 0; } 제가 제대로 이해한건지 헷갈리네요...강의 2:45 콘솔창에서 한글이 깨지는 이유는 텍스트 파일의 인코딩 방식은 UTF8(== 인코딩방식 == 코드페이지)인데 콘솔창의 인코딩 방식과 다르기 때문이 맞나요?원본.txt에 담겨있는 데이터는 컴퓨터 내부에서 바이너리로 저장되어있습니다. (프로그램을 통해 인코딩을 해도 이 바이너리 데이터 자체는 바뀌지않음)이 바이너리 데이터를 메모장은 UTF8 인코딩 방식을 통해서 인코딩 한 후 출력하기 때문에 메모장에서는 한글이 제대로 출력 되는 것이고,프로그램은 이 바이너리 데이터를 그대로 읽어왔지만 콘솔창의 인코딩 방식은 UTF8이 아니기 때문에 인코딩 과정에서 한글은 제대로 인코딩이 안되고 그렇기에 한글은 깨지는것. 그러므로 SetConsoleOutputCP(CP_UTF8);를 통해 콘솔창의 인코딩방식을 UTF8로 바꾸어 준 후 실행하면 한글이 제대로 출력 됨.마지막으로 복사한 사본.txt파일의 데이터는 원본.txt에 담겨있는 바이너리 데이터 그 자체를 그대로 복사한 것이고 그것을 메모장에서 열면 인코딩방식이 일치하기에 사본.txt파일은 한글이 깨지지 않는다.맞을까요? 감사합니다!!!
-
해결됨Windows 시스템 프로그래밍 - 기본
세마포어 예제 소스 코드 문의
안녕하세요 강사님세마포어 개념을 이해하려고 노력중입니다 ㅎㅎ강의 보며 소스코드를 따라치면서 이해해보도록 노력하고 있습니다.아래와 같이 실행하니, 보안에러가 발생하고 있습니다.혹시 제가 소스코드를 잘못작성한건지, 실행환경설정을 바꿔주면 실행되는지 문의 드립니다.#define CRTSECURE_NO_WARNINGS #include <iostream> #include <string.h> #include <Windows.h> #include <process.h> #include <conio.h> // Semaphore를 이용한 동기화 HANDLE g_hSema; TCHAR g_StringList[10][64] = { 0 }; UINT WINAPI ThreadSemaphore(LPVOID param) { int nIndex = (int)param; while (TRUE) { ::wsprintf(g_StringList[nIndex], TEXT("%d thred is Waiting"), nIndex); ::Sleep(500); DWORD dwResult = ::WaitForSingleObject(g_hSema, INFINITE); // g_hSema이 끝나기를 ::wsprintf(g_StringList[nIndex], TEXT("%d thred is Selected##"), nIndex); ::Sleep(500); ::ReleaseSemaphore(g_hSema, 1, NULL); } return 0; } int main(void) { g_hSema = ::CreateSemaphore(NULL, 3, 3, NULL); UINT nThreadId = 0; HANDLE hThread = NULL; // 핸들 생성 for (int i = 0; i < 10; i++) { hThread = (HANDLE)::_beginthreadex( NULL, 0, ThreadSemaphore, (LPVOID)i, 0, &nThreadId); } while (1) { system("cls"); for (int i = 0; i < 10; i++) { putws(gStringList[i]); } ::Sleep(1000); } return 0; } <에러 문구>
-
해결됨Windows 시스템 프로그래밍 - 기본
명시적 로딩 dll의 thread attach 관련 여쭤볼 부분이 있습니다
예시로 보여주신 부분 중에 명시적으로 main thread 에서 dll을 로딩하고 추가적인 thread를 생성했을 때 dllmain의 thread attach 이벤트가 호출되는데 얘기해주시는 설명에서는 thread 마다 dll을 명시적으로 로딩하고 프리해줘야 사용할 수 있다고 해주셔서요추가적으로 만든 thread에서 dll 명시적 로딩을 하지 않음에도 main thread에서 명시적 로딩한 dll의 dllmain의 thread attach 가 호출되는 부분이 궁금합니다 다른 thread에서 main thread 에서 명시적 로딩한 dll의 hmodule과 함수포인터를 얻어와 바로 사용해도 되는걸까요?강의 감사합니다!
-
미해결홍정모의 따라하며 배우는 C언어
2.10 디버거 사용법 5:38
선생님이 하신대로 코드 쓰고 F11 눌렀는데요 첨부한 사진처럼 밑에 이름이랑 값이 안떠요.. 왜 이러는건가요?
-
해결됨홍정모의 따라하며 배우는 C언어
배열과 포인터와 포인터 산술 연산의 이해
안녕하세요, 집에서 해당 강의로 입문한 독학러 입니다.제가 배열과 메모리, 포인터와 산술 연산을 제 기준으로 쉽게 풀어서 이해를 하였는데 이해한게 맞는건지 확인을 부탁드리고자 글을 작성하게 되었습니다.포인터변수의 크기포인터변수의 크기는 자료형이 무엇이든 x86(32비트)에선 4바이트, x64(64비트)에선 8바이트가 나왔습니다. 이러한 이유가 메모리주소에서 확인할 수가 있었는데 일단 x86(32비트)에선 왜 4바이트가 나오냐에 대한 생각인데 메모리 주소를 포인터 변수에 저장한다고 가정했을 때 메모리 주소도 값이잖아요?해당 값을 일단 출력해보면 아래와 같이 나옵니다.이 사진으로 생각할 수 있는건 16진수의 8자리 그리고 4바이트. 즉 4바이트가 표현할 수 있는 가짓수는 2^32 = 4,294,967,2960 ~ 4,294,967,295까지 여기서 4,294,967,295는 16진수로 FFFFFFFF. 위 사진의 자릿수와 같은 8자리다.즉 메모리 주소의 가짓수는 unsigned int과 마찬가지로 4,294,967,296만큼 가질 수 있으며 00000000 ~ FFFFFFFF 이기 때문에 x86(32비트)에선 포인터 변수는 해당 16진수의 값을 저장해야 하니 4바이트인 것이다. x64(64비트)에서도 위와 동일한 이유로 8바이트가 되는 것이다, 라고 이해했습니다. 맞게 이해했을까요??배열과 포인터의 산술연산배열과 포인터의 산술연산을 보고 제일 먼저 떠오른게 "주사위 게임"이였습니다.일단 배열을 선언하면 1차든 2차배열이든 몇겹이든 메모리 공간에 1차원적으로 차례대로 나열되어 메모리 공간이 확보되는걸 선생님 강의를 통해 이해했는데요. 이 메모리를 주사위 게임의 게임판 처럼 변형하여 생각을 해본다면 아래와 같이 될 것 같습니다.<- 배열의 메모리공간 가정주사위 놀이판을 편집을 해왔습니다.여기서 위 그림대로 배열을 선언한다 가정했을 때 arr[3][5]가 될 것 입니다.1~5까진 arr[0][0] ~ arr[0][4]6~10까진 arr[1][0] ~ arr[1][4]11~15까진 arr[2][0] ~ arr[2][4]자료형을 적지않은 이유는 1바이트 자료형이든 4바이트 자료형이든 저 위 그림 한칸 한칸을 하나의 인덱스라고 생각해주시면 될 것 같습니다.만약 int 4바이트라고 가정한다면 위 그림 1번칸엔 메모리 주소 0~3까지 있을 것이고 2번칸엔 4~7까지 있다고 생각할 수 있습니다.그러면 이제 저 주사위놀이판 위에 이제 말을 배치해야 인덱스칸에 접근할 수 있다고 생각해봅시다.그럼 그 말은 포인터변수가 될 것입니다.*ptr = arr; 여기서 arr은 &arr[0][0] 즉 메모리의 첫주소 값을 가지고 있기 때문에 이게 몇차원 배열이든 배열변수의 이름만 적어서 포인터변수에 첫 주소를 저장합니다.그러면 이제 1번칸에 말이 접속하여 인덱스에 포인터변수로 접근할 수 있게 된다고 생각했습니다.1번칸은 [0][0] 여기서 5번칸 [0][4]으로 이동한다고 가정 한다면 4칸을 이동해야 합니다.그러면 여기서 말에다가 4칸을 더하면 ptr += 4;을 하면 포인터변수의 주소는 [0][4]을 가리키고 있을 것 입니다. 여기서 바꿔 생각한다면[0][4]가 아니라 [0][i] 라고 했을 때 ptr += i; 을 더하면 [0][0] ~ [0][i] 까지 이동할 수 있을 것 입니다.위 방법대로 한다면 1차원이든 2차원이든 3차원이든 배열 맨 끝 [인덱스]에 포인터 변수로 접근할 수 있다고 생각합니다.그러면 이제 1번칸 [0][0]에서 6번칸 [1][0]에 가고 싶다고 가정을 한다면 총 5칸을 가야 도달할 수 있습니다.왜냐하면 arr[3][5]으로 선언했기 때문에 뒤에 [5]인덱스가 0~4까지 총 5가짓수이기 때문입니다.그러면 포인터변수(말)에게 ptr+=1*5을 하면 6번칸 [1][0]에 도달할 수 있습니다.1번칸 [0][0]에서 11번칸 [2][0]에 갈려면 ptr += 2*5을 하면 됩니다. 즉 이걸 바꿔서 생각해본다면[0][0]에서 [j][0]로 가기 위해서는 ptr += j * 5(인덱스 총 갯수)을 이용하면 옮겨갈 수 있습니다.여기서 빼기도할 수 있는데현재 ptr이 [0][0]에 있다고 가정하고 ptr += 2 * 5를 하면 [2][0]으로 가게 되는데 여기서 [1][0]으로 간다고 가정하면 ptr += -1 * 5를 하면 [1][0]으로 가게 된다. 위와 같은 방식으로 배열에 포인터변수로 접근하여 사용하니까 아주 쉽게 사용이 되더라구요, 반복문에서는 따로 위 그림처럼 포인터변수 = 말, 배열 = 주사위게임판 이라 생각하고 머릿속에 그리면서 하니까 원하는 값을 얻을 수 있고 이러한 방식이 괜찮은 방법 중 하나일까요? 아니면 잘못 이해하고 있는걸까요? 문장 정리능력이 없다보니 이렇게 긴 글을 적어놨는데 읽어주시면 감사하겠습니다.
-
미해결홍정모의 따라하며 배우는 C언어
static변수(정적변수)에 변수를 넣으면 안되나요?
강의 15:16 처럼3차원 배열의 인덱스 c + col r + (col row) *d)를함수를 통해 사용해보려 했습니다.#include <stdio.h> #include <stdlib.h> int row = 3, col = 2, depth = 2; int idx3(int c, int r, int d) { static const cr = col * row; return c + col * r + cr * d; } int main() { int* ptr = (int*)malloc(sizeof(int) * row * col * depth); if (!ptr) exit(1); for (int d = 0; d < depth; d++) for (int r = 0; r < row; r++) for (int c = 0; c < col; c++) ptr[idx3(c, r, d)] = idx3(c, r, d); for (int d = 0; d < depth; d++) { for (int r = 0; r < row; r++) { for (int c = 0; c < col; c++) printf("%d", ptr[idx3(c, r, d)]); printf("\n"); } printf("\n"); } return 0; } 실행시켰더니 expression must have a constant value라고 뜨면서 에러가 납니다.표현식은 상수를 가져야한다는 뜻인것같습니다.Q1. static변수 cr에 col *row를 넣었기때문인것같은데 원인이 무엇인가요?정적변수에는 변수를 넣으면 안되는건가요? Q2. 또 강의 15:30에서 static을 통해 cr을 사용하면 속도가 빨라지는 이유는 정적 변수 cr은 프로그램이 끝날 때까지 계속 메모리에 남아있으므로 초기화를 1번만 해주기 때문에 이후에는 연산을 할 필요가 없어서 그런것 맞나요?감사합니다!!!
-
해결됨홍정모의 따라하며 배우는 C언어
9-18. 포인터형 매개변
안녕하세요!강의 마지막 코드를 제가 제대로 이해했는지 궁금하여 질문 드립니다. #define CRTSECURE_NO_WARNINGS#include <stdio.h>void swap(int* u, int* v){printf("%p %p\n", u, v);int temp = *u;u = v;*v = temp;}int main(){int a = 123;int b = 456;printf("%p %p\n", &a, &b);swap(&a, &b);printf("%d %d\n", a, b);return 0;} a와 b의 주소 값이 매개 변수의 값으로서 함수 swap()에 입력된다.즉 int* u = &a가 되고, int* v = &b가 된다.swap() 함수의 변수 u는 main() 함수의 변수 a의 주소가 저장된 포인터 변수가 됐고, v또한 마찬가지다. u, v에 각각 a와 b의 주소 값이 저장됐기 때문에 이것을 실행하면 main() 함수의 a, b의 주소 값과 동일하게 출력된다.이후 변수 temp에 변수 a의 주소를 redirection 하여, 해당 주소 안에 저장된 값을 대입한다(a의 주소로 접근 -> 주소 안에 있는 값 123 temp에 대입).a의 주소로 직접 접근하여 그 주소의 값을 b의 주소 안에 저장된 값으로 변경한다.이후 b의 주소로 직접 접근하여 그 주소의 값을 변수 temp의 저장된 값으로 변경한다.swap() 함수에서 a, b의 주소로 직접 접근해 값을 변경했기 때문에 함수들의 영역이 달라도 main() 함수 변수들의 값은 정상적으로 swap 된다. 감사합니다.
-
미해결홍정모의 따라하며 배우는 C언어
오류 이유가 궁금합니다
int main(){ int count = 0; while (1) { printf("Current count is %d. Continue?(y/n)\n", count); if (getchar() == 'n') break; else if (getchar() == 'y') count++; else printf("Please input y or n\n"); while (getchar() != '\n') continue; } return 0;} 강의에서 int c = getchat() 해서 c를 사용하니까 잘 되던데, if문이랑 else if문에 getchar()을 그대로 넣으면 왜 오류가 나는지 궁금합니다!