| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- ubuntu
- 가상머신
- 티스토리챌린지
- FreeBSD
- node.js
- 인프라
- 연습문제
- 퇴근길
- K&R
- podman
- Flutter
- 에러
- 휘발류
- Bloc
- 잡담
- 템플릿
- 오블완
- virtualmachine
- 일상
- 주유소
- Linux
- 오토바이
- DART
- VMware
- 객체지향프로그래밍
- 개발
- VM
- C언어
- 개발기
- 리눅스
- Today
- Total
그냥저냥
문제풀이 | The C Programming Language (K&R): Exercise 1-1 본문
문제풀이 | The C Programming Language (K&R): Exercise 1-1
sync86 2026. 4. 25. 14:04
책: The C Programming Language (K&R)
본문의 연습문제는 저작권 이슈로 그 내용을 직접적으로 언급하지 않습니다. 이점 양해 바랍니다.
처음에 아무 생각없이 이 책을 펼쳤는데, The C Programming Language Exercise 1-1을 보며 생각보다 봐야할 게 많다는 사실에 깜짝 놀랐는데, 어떤 내용을 확인해야 하는지 간단하게 정리를 해보았습니다.
Exercise 1-1 풀기전에 확인해야 할 것!
이 책의 초판 발행 년도,
1978년, 제가 가지고 있는 것은 1988년 개정된 2판인데,
초판 발행년도를 감안하면 이 문제는 본인의 시스템에서 "hello, world" 소스코드를 작성하고 컴파일할 수 있는 환경을 직접 구성해보라는 주문에 더 가까운 것 같아요.
왠지 그런 느낌이 듭니다.
당시에는 컴파일러가 이 책의 저자들이 만든 컴파일러가 전부였던 것 같습니다.
책 내용 중에 컴파일러 설치하는 방법에 대해서는 다루지 않고 있습니다.
그런 의미에서 확실히 최근 출간된 책에 비해 불친절하다는 생각이 드네요.
$ cc hello.c
현재는 MSVC, gcc, clang 등 많은 컴파일러가 나와 있습니다.
그래서 이러한 컴파일러를 직접 설치하고 구성할 수 있어야 할 것 같습니다.
설명은 생략하겠지만, 구글에 "OOO에서 OOO 설치 방법", "OOO에서 OOO 컴파일 방법"이라고 검색하면 다 나옵니다.
위와 같이 명령어를 실행하고 컴파일이 정상적으로 잘 되었다면 아래와 같이 a.out 파일이 생성되는데, 이 파일명을 바꿀 수 있습니다.
여기서는 꼭 사용하고 계시는 컴파일러 메뉴얼을 확인해야 해요.
$ ls
a.out hello.c
사실 아래와 같이 -o (소문자) 옵션을 사용하여 원하는 출력되는 파일명을 작성하면 됩니다.
물론 출력되는 파일명 옵션에 대해서 알려드렸습니다.
다만, 책에서는 이 옵션에 대해 언급이 없었습니다.
그래서 이 옵션을 사용하지 않는다고 가정하겠습니다.
$ cc -o hello ./hello.c
C언어의 표준. C89 -> C99 이후 - 최신 표준은 C23 (ISO/IEC 9899:2024)
최근 컴파일러에서 컴파일할 때 오류가 생길 여지가 많아집니다.
책에서 소스코드는 무심하게 아래와 같이 되어 있는데, 최근 컴파일러가 C99 표준 이상을 지원하는 경우가 많습니다.
따라서 아래와 같이 작성하면 컴파일러가 투덜되거나 컴파일을 거절할 수 있다는 점 유의해야 합니다.
#include <stdio.h>
main()
{
printf("hello, world\n");
}
아래와 같이 변경하는게 좋을 것 같습니다.
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
아니면 아래의 스타일로 해야 합니다. 개인적으로 가장 선호하는 스타일입니다.
#include <stdio.h>
int main(int argc, char** argv)
{
printf("hello, world\n");
return 0;
}
main() 함수의 파라미터를 사용하지 않을 거면, 아래와 같은 가이드를 제공하는 곳도 있었습니다.
#include <stdio.h>
int main(int /*argc*/, char** /*argv*/)
{
printf("hello, world\n");
return 0;
}
다만, 제가 테스트 했을 때 결과는 아래의 표와 같습니다.
| 구분 | 내용 |
| gcc | 경고, 오류 없음 |
| clang | 경고 (아래 코드 블록 참고) |
$ cc --version
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ cc ./hello.c
hello.c:4:24: warning: omitting the parameter name in a function definition is a C23 extension [-Wc23-extensions]
4 | int main(int /* argc */, char** /* argv */)
| ^
hello.c:4:43: warning: omitting the parameter name in a function definition is a C23 extension [-Wc23-extensions]
4 | int main(int /* argc */, char** /* argv */)
| ^
2 warnings generated.
과거 오픈소스 코드를 보다가 아래와 같은 코드를 봤던 기억이 있습니다.
gcc에서는 문제가 없을 것으로 보이지만, clang에서는 역시 유사하게 경고를 확인하였습니다.
#include <stdio.h>
int main(argc, argv)
int argc;
char** argv;
{
printf("hello, world\n");
return 0;
}
$ cc --version
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ cc ./hello.c
./hello.c:4:5: warning: a function definition without a prototype is deprecated in all versions of C and is not supported in C23 [-Wdeprecated-non-prototype]
4 | int main(argc, argv)
| ^
1 warning generated.
C언어 표준에 따른 main() 함수 변천
| 구분 | K&R 스타일 (1978/1988) | 현대적 스타일 (C99~C23) |
| 반환 타입 | main() (암묵적으로 int형 반환) | int main(void) (명시적) |
| 파라미터 | main(argc, argv) {} | int main(int argc, char** argv) {} |
| 반환값 | 생략 가능 (Undefined) | return 0; (성공 반환 명시) |
경고와 에러 메시지의 차이
컴파일러를 사용하여 컴파일할 때 종종 경고나 에러 메시지를 볼 수 있습니다.
차이는 아래의 표와 같습니다.
| 구분 | 설명 |
| 경고 | 경고 메시지만 출력되고, 컴파일은 진행됩니다. 다만, 경우에 따라서는 프로그램이 실행 중 의도하지 않는 동작을 하거나 중단될 수 있습니다. |
| 에러 | 에러 메시지 출력되며 컴파일은 중단됩니다. 결과 파일인 a.out 파일이 만들어지지 않으므로 반드시 수정해야 합니다. |
반환값 용도
아마도 main() 함수에서 반환값은 위에 작성한 코드와 같이 묻지도 따지지도 않고 return 0; 코드를 작성했을 겁니다.
하지만, 이 반환값 용도는 운영체제에서 어플리케이션 종료한 상태를 확인을 위한 용도이죠.
컴파일이 정상적으로 실행되고, 결과물을 실행한 후 쉘에서 아래와 명령어로 확인할 수 있습니다.
참고로 이 명령어 실행 결과에 해당되는 소스코드 및 컴파일 방법은 설명하지 않는데, 위에서 언급했으니 넘어가겠습니다.
$ ./a.out
$ echo $?
0
위의 결과는 당연히 return 0;에 해당되는 결과이구요. 만약에 return 1;로 했다면 echo $?의 결과는 1이 나올겁니다.
#include <stdio.h>
int main(int argc, char** argv)
{
printf("hello, world\n");
return -1;
}
그렇다면 return -1;로 수정하고 echo $? 명령을 실행하면 어떤 결과를 내줄까요?
$ ./a.out
$ echo $?
255
즉, 쉘에서 나타낼 수 있는 값의 범위는 0~255임을 확인할 수 있습니다.
근데 왜? 255까지일까요?
이 부분은 이번 내용에서 벗어난다고 생각해서 제외하겠습니다.
더 파야 하지만, 이번 포스팅에 내용에서 벗어나는 것 같습니다.
Exercise 1-1 두번째, 요구사항
망가뜨려라.
의도적으로 코드를 망가뜨렸들 때, 어떤 오류가 나오는지 확인해봐야 합니다.
첵에서는 아래와 같은 코드만 나오는 것 같습니다.
#include <stdio.h>
main()
{
printf("hello, world\n
");
}
위의 코드는 책에서 소개된 코드이고, 실제로 코드는 아래와 같이 작성하였습니다.
#include <stdio.h>
int main(int argc, char** argv)
{
printf("hello, world\n
");
return 0;
}
이후 빌드와 컴파일, 2개의 경고, 2개의 에러로 실패하였습니다.
일단은 쌍따옴표 사이에 줄바꿈은 허용되지 않는다 정도로만 확이하면 될 것 같습니다.
$ cc --version
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ cc ./hello.c
./hello.c:5:12: warning: missing terminating '"' character [-Winvalid-pp-token]
5 | printf("hello, world\n
| ^
./hello.c:5:12: error: expected expression
./hello.c:6:5: warning: missing terminating '"' character [-Winvalid-pp-token]
6 | ");
| ^
./hello.c:8:2: error: expected '}'
8 | }
| ^
./hello.c:4:1: note: to match this '{'
4 | {
| ^
2 warnings and 2 errors generated.
마무리
과거 사회 초년생 때, C언어로 프로젝트 경험한 이력이 있습니다.
다만, 옛날에 봤다면 몰랐을 내용인데, 경력이 쌓이다 보니 기존에 보이지 않았던 부분들이 보이기 시작하네요.
다음은 "The C Programming Language: Exercise 1-2" 문제 풀어보겠습니다.
'개발기 > The C Programming Language' 카테고리의 다른 글
| 문제풀이 | The C Programming Language (K&R): Exercise 1-6 (0) | 2026.05.23 |
|---|---|
| 문제풀이 | The C Programming Language (K&R): Exercise 1-5 (0) | 2026.05.04 |
| 문제풀이 | The C Programming Language (K&R): Exercise 1-4 (0) | 2026.05.04 |
| 문제풀이 | The C Programming Language (K&R): Exercise 1-3 (0) | 2026.04.28 |
| 문제풀이 | The C Programming Language (K&R): Exercise 1-2 (0) | 2026.04.28 |