반응형
#include <stdio.h>
int main(void)
{
char ch = 'A';
printf("A");
printf("%c", 'A');
printf("%c", 65);
printf("%c", 'B' - 1);
printf("%c", 'C' - 2);
printf("%c", ch);
printf("%s", "A");
printf("%X", 10);
putchar('A');
putchar(ch);
putchar(65);
putc('A', stdout);
puts("A");
return 0;
}
stdout은 대상을 출력하라는 뜻이다.
위의 코드는 A를 출력하는 다양한 방법이며 정답은 없다.
실행결과
AAAAAAAAAAAAA
출력되는건 당연 A밖에 안나온다.
전처리기 개요
- 전처리기는 컴파일하기 전에 프로그램에 대한 일련의 작업을 수행
- 일반적으로 main()함수 외부에 작성
- 기계어 코드를 생성하지 않으며 소스 코들르 컴파일하기 좋게 가공한다.
- 모든 전처리기는 #기호를 명령어 앞에 붙이고 마지막에 문장의 끝을 나타내는 세미콜론;을 사용하지 않는다
- stdio.h 등의 표준헤더 파일에서 많이 볼 수 있고 #include, #define이 대표적이다.
| 기능 | 전처리기 | 예 |
| 매크로 정의 | #define, #undef | #define PI 3.14, #undef SIZE |
| 외부 파일 포함 | #include | #include <stdio.h> |
| 조건부 컴파일 | #if, #elif, #else, #endif#ifdef, #ifndef | #if _MSC_VER > 1000#endif |
| 사용자 정의 컴파일 에러 | #error, #line | #error C++ compiler required.#line 100 line.c |
| 문자열화 | # (stringification operator) | ST(ii) → #ii |
| 토큰 연결 | ## (token pasting operator) | plus(a) → a##1 + a##2 |
| 컴파일러 옵션 설정 | #pragma | #pragma once#pragma warning(disable:4996) |
f7키를 누른다고 바로 컴파일을 하는게 아닌 전처리 #define #include를 먼저 읽는다.
#define문 : 매크로 , 함ㅁ수같은 매크로
문자만 오는 경우는 매크로 상수라고 한다
- #define PI 3.141592
매개 변수가 있는 함수같은 매크로
- Macros with arguments
- 매크로 함수라고도 한다
- #define SUM(i,j) (i+j)
구분하는 법은 가로가 있으면 매크로 함수
가로가 없으면 매크로 상수이다.
#define PI 3.14... 을 하면 컴파일 하기전에 PI라는 이름은 전부 3.14로 바뀐다
#define _CRT_SECURE_NO_WARNINGS
//#pragma warning(disable:4996) //컴파일러 기능을 지정하는 전처리기
#include <stdio.h>
int main(void)
{
int num;
printf("숫자 하나를 입력하세요=");
scanf("%d", &num);
printf("입력받은 수는 %d 입니다.\n", num);
return 0;
}
#define CRT는 반드시 맨 윗단에 사용해야한다.
또는
pragma를 사용해도 된다.
MSVC GCC
| 항목 | MSVC(Microsoft Visual C++) | GCC (GNU Compiler Collection) |
| 플랫폼 | Windows 중심 | Windows, macOS, Linux 등 다중 플랫폼 |
| 개발사 | Microsoft | GNU Project (오픈소스) |
| 사용 환경 | Visual Studio IDE와 연동 | 리눅스 기본 컴파일러, VS Code, CLI 등 다양하게 사용 가능 |
| 표준 지원 | C/C++ 표준 지원 (다소 보수적일 수 있음) | C/C++ 표준을 빠르게 반영 (최신 기능 잘 지원) |
| 컴파일러 옵션 문법 | cl 명령어로 컴파일 (cl test.c) | gcc 또는 g++ 명령어 (gcc test.c) |
| 바이너리 형식 | .exe (Windows 전용 포맷) | 플랫폼에 맞는 실행 파일 생성 (a.out, .exe, ELF 등) |
| 경고 및 오류 메시지 | Microsoft 방식의 포맷 | GNU 스타일의 포맷 |
| 확장 기능 | Microsoft 전용 확장 문법 사용 가능 | POSIX 호환성 좋음, 리눅스 친화적 |
| 속도 | 최적화 수준 높음 (특히 Windows 프로그램에서 유리) | 최적화 다양, 커맨드라인 조합으로 유연함 |
| 라이선스 | 상용 (Visual Studio 포함), 무료 Community 버전도 있음 | 완전 오픈소스, 자유롭게 사용 가능 |
디버그 모드와 릴리즈 모드의 차이점
| 구분 | 디버그(Debug) 모드 | 릴리즈(Release) 모드 |
| 목적 | 개발 중 버그 찾기, 코드 분석 | 성능 최적화된 최종 프로그램 배포용 |
| 최적화 여부 | 거의 없음 (코드 구조 보존) | 컴파일러 최적화 적용 (속도, 용량 개선) |
| 디버깅 정보 | 포함됨 (.pdb 등 디버깅 심볼 생성) | 없음 또는 최소화 |
| 파일 크기 | 큼 (디버깅 정보 때문에) | 작음 (불필요한 정보 제거) |
| 속도 | 느림 (디버깅 정보 + 최적화 없음) | 빠름 (최적화 적용됨) |
| 오류 검사 | 런타임 오류 체크 포함 (예: 배열 경계 초과 등) | 대부분 생략됨 (성능 우선) |
| 로그/출력 | 디버그용 로그 출력 포함 가능 | 불필요한 출력 제거 |
| 사용 예시 | 개발자용, 테스트, 코드 분석 | 사용자 배포용, 최종 제품 |
| 빌드 설정 명령어 예시 (GCC) | gcc -g -o program program.c (디버그 정보 포함) | gcc -O2 -o program program.c (최적화 포함) |
미리 정의된 매크로
| 기정의 매크로 | 기능 |
| __DATE__ | Mmm dd yyyy 형태로 전처리기 실행(컴파일) 날짜 |
| __FILE__ | 소스 파일의 이름 |
| __LINE__ | 행 번호 |
| __TIMESTAMP__ | 전처리기가 실행된(컴파일한) 날짜와 시간 |
| __TIME__ | 전처리기가 실행된(컴파일한) 시간 |
#include <stdio.h>
2. int main(void)
3. {
4. printf("__LINE__=%d\n",__LINE__);
5. printf("__DATE__=%s\n",__DATE__);
6. printf("__LINE__=%d\n",__LINE__);
7. printf("__TIME__=%s\n",__TIME__);
8. printf("__TIMESTAMP__=%s\n",__TIMESTAMP__);
9. printf("__FILE__=%s\n",__FILE__);
10. return 0;
11. }
실행결과
__LINE__=45
__DATE__=Apr 14 2025
__LINE__=47
__TIME__=15:34:37
__TIMESTAMP__=Mon Apr 14 15:34:33 2025
__FILE__=chapter6.c
미리 정의된 매크로는 언더스코어__ 를 항상 2번 사용해줘야한다.. 실수 금지
실습
이름, 4과목의 성적을 입력받아 이름, 총점, 평균 출력:매크로 활용
#include<stdio.h>
#define AVERAGE(x,y,z,h) (x+y+z+h)/4.0
int main(void){
char name[50];
int eng,kor,math,his,total;
double avg;
printf("이름을 입력해주세요");
scanf("%s",&name);
printf("영어 성적을 입력해주세요 : ");
scanf("%d",&eng);
printf("국어 성적을 입력해주세요 : ");
scanf("%d",&kor);
printf("과학 성적을 입력해주세요 : ");
scanf("%d",&math);
printf("역사 성적을 입력해주세요 : ");
scanf("%d",&his);
total = eng + kor + math + his;
avg = AVERAGE(eng,kor,math,his);
printf("%s님의 총점은 %d 이며 평균은 %f입니다",name, total,avg);
}
이름을 적을떄 scanf를 사용하면 공백을 만날때 값이 이상해져버린다
해결방법은
gets(name)을 사용하면 되지만 보안이슈가 있고
gets_s(name,50)<-50은 배열수를 입력 이렇게 사용하면 되지만 리눅스나 맥에서는 작동이 안된다
fgets(name,sizeof(name),stdin);을 사용하여 받아주면 된다.
여기서 fgets은 \n 개행을 자동으로 받게 되는데
이걸 없애는 방법은
#include<string.h> // 선언해줘야함
name[strcspn(name, "\n")] = '\0'; // ← 여기 추가
이걸 사용해주면 개행을 제거해
최종 출력값에
1 2 2님의 총점은 492 이며 평균은 123.00입니다
이렇게 나온다
반응형
'c프로그래밍 > Class' 카테고리의 다른 글
| C++ 5주차 CLASS (0) | 2025.10.01 |
|---|---|
| C언어 7주차 Class (0) | 2025.04.21 |
| C언어 4주차 class (0) | 2025.04.10 |
| C언어 3주차 (0) | 2025.03.24 |
| C언어 기초 2주차 (5) | 2025.03.17 |
