시리즈:쉽게 배우는 프로그래밍 입문/C 편집하기

편집하면 당신의 IP 주소가 공개적으로 기록됩니다. 계정을 만들고 로그인하면 편집 시 사용자 이름만 보이며, 위키 이용에 여러 가지 편의가 주어집니다.

편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.

최신판 당신의 편집
1번째 줄: 1번째 줄:
{{:시리즈:쉽게 배우는 프로그래밍 입문}}
{{쉽게 알 수 있다 시리즈|이 문서는 정말 쉽습니다.|문서의 내용이 너무 쉬워서 오늘부터 프로그래밍 할 수 있을 것 같습니다.}}
 


=== 준비 ===
=== 준비 ===
C 언어를 공부할 때는 준비물은 '이론상으로' 단 두 가지만 있으면 된다. 바로 코드를 작성할 텍스트 편집기와, 그 코드를 프로그램으로 만들어주는 컴파일러가 그것이다. [[문서 편집기]]는 [[메모장]](윈도우), vi(멀티 플랫폼), gedit(리눅스), kate(리눅스), mousepad(리눅스), 비주얼 스튜디오 코드(멀티 플랫폼) 등을 일컬으며, 컴파일러는 대표적으로 gcc(멀티 플랫폼)가 있다. 그러나 이 두 가지만으로 프로그래밍을 하는 것은 매우 불편하므로, 보통은 통합 개발환경(IDE)을 사용한다. 이건 '문서 편집기와 컴파일러와 이것저것 유용한 기능이 들어 있는 프로그램'으로, 프로그래밍을 더욱 편하게 할 수 있게 해 준다. 또한 이것이 입문자에게도 쉬운 방법이기에, 대개 이 방법으로 많이 배운다.
C 언어를 공부할 때는 준비물은 '이론상으론' 단 두 가지만 있으면 된다. 바로 코드를 작성할 텍스트 편집기와, 그 코드를 프로그램으로 만들어주는 컴파일러가 그것이다. [[문서 편집기]]는 [[메모장]](윈도), vi(멀티 플랫폼), gedit(리눅스), kate(리눅스), mousepad(리눅스) 등을 일컬으며, 컴파일러는 대표적으로 gcc(멀티 플랫폼)가 있다. 그러나 이 두 가지만으로 프로그래밍을 하는 것은 매우 불편하므로, 보통은 통합 개발환경(IDE)을 사용한다. 이건 '문서 편집기와 컴파일러와 이것저것 유용한 기능이 들어 있는 프로그램'으로, 프로그래밍을 더욱 편하게 할 수 있게 해 준다. 또한 이것이 입문자에게도 쉬운 방법이기에, 대개 이 방법으로 많이 배운다.


== 윈도우 ==
IDE는 [[윈도우 7]] 이상에서라면 Visual Studio Community를 다운로드 받아 설치하자.
IDE는 [[윈도우 7]] 이상에서라면 Visual Studio Community를 다운로드 받아 설치하자. 이클립스나 코드블럭을 사용해도 된다.


== 리눅스 ==
[[리눅스]]에서는 두 가지 방법이 있는데,  
[[리눅스]]에서는 두 가지 방법이 있는데,  


첫 번째는 이클립스를 사용하는 것. 다만 이클립스는 원래 Java 프로그래밍에 쓰이는 IDE라서 C 언어에는 쓸 수 없는데, 이것을 C 언어에 사용하기 위해서는 이클립스 CDT라는 플러그인이 필요하다. 또한 앞서 언급한 컴파일러인 GCC의 설치도 필요하다. 즉 리눅스에서는 이클립스와 이클립스CDT와 GCC를 모두 설치해야 한다. 설치하는 방법은 아래 문단에 적혀있다.
첫 번째는 이클립스를 사용하는 것. 다만 이클립스는 원래 Java 프로그래밍에 쓰이는 IDE라서 C 언어에는 쓸 수 없는데, 이것을 C 언어에 사용하기 위해서는 이클립스 CDT라는 플러그인이 필요하다. 또한 앞서 언급한 컴파일러인 GCC의 설치도 필요하다. 즉 리눅스에서는 이클립스와 이클립스CDT와 GCC를 모두 설치해야 한다. 설치법은 매우 간단한데, 시냅틱 패키지 관리자를 열고 eclipse와 eclipse-cdt와 gcc를 검색해서 체크를 하고 적용을 눌러주기만 하면 설치된다. 시냅틱 패키지 관리자가 없다면, 터미널을 열고 1. sudo apt-get install gcc 2. sudo apt-get install eclipse 3. sudo apt-get install eclipse-cdt를 입력해주자. 이것만으로 설치가 끝난다. 


두 번째 방법은 코드 블럭(Code::Blocks)을 사용하는 것이다. 코드블럭을 설치 하려면 sudo apt-get install libsdl1.2-dev codeblocks 를 입력하면 끝이다. 이클립스보다 간단한가? 이클립스는 따로 플러그인이 필요하지만, Code::Blocks은 애초에 C, C++을 기준으로 만들어진거라 플러그인<del>그런거 없다</del>이 필요 없다.
두 번째 방법은 코드 블럭을 사용하는 것이다. 코드블럭을 설치 하려면 sudo apt-get install libsdl1.2-dev codeblocks 를 입력하면 끝이다. 이클립스보다 간단한가? 이클립스는 따로 플러그인이 필요하지만, Code::Blocks은 애초에 C, C++을 기준으로 만들어진거라 플러그인<del>그런거 없다</del>이 필요 없다.


[[OS X]]의 경우에는 [[Xcode]]를 다운 받으면 된다. 리눅스와 달리 초반에 터미널을 이용하는 것이 좀 귀찮다. Xcode를 다운 받은 후, 런치패드>>기타 응용프로그램>>터미널 선택 한 후에 xcode-select --install 을 입력한 후에 엔터를 누른다. 그 후에 뭔가 하라는 인스톨은 안하고 별 이상한 것들이 나오는데, 그냥 쭉 내려서 agree를 하면 그때부터 설치하겠냐는 창이 뜬다. 설치를 누르고 기다리고 있으면 사용이 가능해진다. 리눅스에서는 gcc로 컴파일을 하는데 OS X에서는 clang도 사용할 수 있다. 리눅스에서도 clang을 설치하면 사용할 수 있다.
[[OS X]]의 경우에는 [[Xcode]]를 다운 받으면 된다. 리눅스와 달리 초반에 터미널을 이용하는 것이 좀 귀찮다. Xcode를 다운 받은 후, 런치패드>>기타 응용프로그램>>터미널 선택 한 후에 xcode-select --install 을 입력한 후에 엔터를 누른다. 그 후에 뭔가 하라는 인스톨은 안하고 별 이상한 것들이 나오는데, 그냥 쭉 내려서 agree를 하면 그때부터 설치하겠냐는 창이 뜬다. 설치를 누르고 기다리고 있으면 사용이 가능해진다. 리눅스에서는 gcc로 컴파일을 하는데 OS X에서는 clang도 사용할 수 있다. 리눅스에서도 clang을 설치하면 사용할 수 있다.
27번째 줄: 26번째 줄:
==== 이클립스(CDT) ====
==== 이클립스(CDT) ====
===== 리눅스 =====
===== 리눅스 =====
[[파일:이클립스1.png|링크=Special:FilePath/이클립스1.png]]
[[파일:이클립스1.png]]
[[파일:이클립스2.png|링크=Special:FilePath/이클립스2.png]]
[[파일:이클립스2.png]]
[[파일:Gcc.png]]
[[파일:Gcc.png]]


46번째 줄: 45번째 줄:
다음은 Visual Studio 2013 의 Win32 콘솔 응용 프로그램의 프로젝트 만들기 과정이다.
다음은 Visual Studio 2013 의 Win32 콘솔 응용 프로그램의 프로젝트 만들기 과정이다.


[[파일:프로젝트생성-1.PNG|링크=Special:FilePath/프로젝트생성-1.PNG]]
[[파일:프로젝트생성-1.PNG]]


1. 화면 상단의 파일 - 새로 만들기 - 프로젝트를 클릭한다. ( 단축키는 {{|Ctrl}}+{{|Shift}}+{{|N}}이며, 펼쳐진 파일 탭의 가려진 뒷부분에는 새 프로젝트 만들기가 따로 있다. )
1. 화면 상단의 파일 - 새로 만들기 - 프로젝트를 클릭한다. ( 단축키는 {{키눌림|Ctrl}} + {{키눌림|Shift}} + {{키눌림|N}}이며, 펼쳐진 파일 탭의 가려진 뒷부분에는 새 프로젝트 만들기가 따로 있다. )


[[파일:프로젝트생성-2.PNG|링크=Special:FilePath/프로젝트생성-2.PNG]]
[[파일:프로젝트생성-2.PNG]]


2. 위 과정을 마치고 나면 다음과 같은 창이 뜬다. 이 중에서 Win32 콘솔 응용 프로그램을 클릭하고 이름을 정한 다음 확인을 누른다.
2. 위 과정을 마치고 나면 다음과 같은 창이 뜬다. 이 중에서 Win32 콘솔 응용 프로그램을 클릭하고 이름을 정한 다음 확인을 누른다.


[[파일:프로젝트생성-3.PNG|링크=Special:FilePath/프로젝트생성-3.PNG]]
[[파일:프로젝트생성-3.PNG]]


3. 추가 옵션에서 빈 프로젝트를 체크하고 마침을 누른다.
3. 추가 옵션에서 빈 프로젝트를 체크하고 마침을 누른다.
60번째 줄: 59번째 줄:
==== 이클립스(CDT) ====
==== 이클립스(CDT) ====
==== XCode ====
==== XCode ====
[[파일:XCode C 1.png|링크=Special:FilePath/XCode C 1.png]]
[[파일:XCode C 1.png]]
1. Create a new Xcode project를 누른다.
1. Create a new Xcode project를 누른다.
[[파일:XCode C 2.png|링크=Special:FilePath/XCode C 2.png]]
[[파일:XCode C 2.png]]
2. OSX-Application-Command line tool 선택 후 next
2. OSX-Application-Command line tool 선택 후 next
[[파일:XCode C 3.png|링크=Special:FilePath/XCode C 3.png]]
[[파일:XCode C 3.png]]
3.Language-C 선택후 나머지 란은 알맞게 채워 넣는다.
3.Language-C 선택후 나머지 란은 알맞게 채워 넣는다.


=== [[Hello, World!]]===
=== <s>당연하지만</s> [[Hello, World!]]===
<syntaxhighlight lang=c>
<source lang=c>
#include <stdio.h>
#include <stdio.h>


int main(void)
int main(void)
{
{
    printf("Hello, World!\n");
printf("Hello, World!\n");
    return 0;
return 0;
}
}
</syntaxhighlight>
</source>


또는
또는


<syntaxhighlight lang=c>
<source lang=c>
#include <stdio.h>
#include <stdio.h>


int main(void)
int main(void)
{
{
    puts("Hello, World!");
puts("Hello, World!");
    return 0;
return 0;
}
}
</syntaxhighlight>
</source>


참고로 main(void)의 void는 생략이 가능하다. 엄밀한 의미에서는 다르지만, 그냥 차이가 없다고 받아들이는게 지금은 편하다.
참고로 main(void)의 void는 생략이 가능하다. 엄밀한 의미에서는 다르지만, 그냥 차이가 없다고 받아들이는게 지금은 편하다.
94번째 줄: 93번째 줄:
=== 컴파일하기 ===
=== 컴파일하기 ===
==== 유닉스 환경에서 CLI로 컴파일 ====
==== 유닉스 환경에서 CLI로 컴파일 ====
매우 간단하다. 위에 적힌 Hello World의 코드를 그대로 텍스트 편집기(gedit, kate, mousepad, vi 등)로 작성하고 파일을 저장한다. 파일 확장자는 .c로 한다. 이 파일을 소스코드라고 한다. 가장 많이 쓰는 텍스트 편집기는 vi(vim)이다. 대부분의 유닉스 시스템에는 vi 또는 vim이 설치되어 있을 것이다.
매우 간단하다. 위에 적힌 Hello World의 코드를 그대로 텍스트 편집기(gedit, kate, mousepad, vi 등)로 작성하고 파일을 저장한다. 파일확장자는 .c로 한다. 이 파일을 소스코드라고 한다. 가장 많이 쓰는 텍스트 편집기는 vi(vim)이다. 대부분의 유닉스 시스템에는 vi 또는 vim이 설치되어 있을 것이다.
<syntaxhighlight lang=console>
 
$ vi test.c
  ~$ vi test.c
    혹은
혹은
$ vim test.c
  ~$ vim test.c
</syntaxhighlight>
로 소스코드를 작성할 수 있다.
로 소스코드를 작성할 수 있다.
프로젝트의 규모가 커지면 make파일을 이용하기도 하는데 [[CMAKE]]참조
프로젝트의 규모가 커지면 make파일을 이용하기도 하는데 [[CMAKE]]참조


본격적인 컴파일 과정은 다음과 같다.
본격적인 컴파일 과정은 다음과 같다.
[[파일:컴파일1.png|링크=Special:FilePath/컴파일1.png]]
[[파일:컴파일1.png]]


이것이 우리가 컴파일할 소스코드다. 이 파일이 /home/gabriel/Hive에 test.c라는 이름으로 저장되어 있다고 치면
이것이 우리가 컴파일할 소스코드다. 이 파일이 /home/gabriel/Hive에 test.c라는 이름으로 저장되어 있다고 치면




[[파일:컴파일2.png|링크=Special:FilePath/컴파일2.png]]
[[파일:컴파일2.png]]


터미널을 키고
터미널을 키고  
<syntaxhighlight lang=console>
  ~$ cd /home/gabriel/Hive
$ cd /home/gabriel/Hive
라고 입력하여 저장되어 있는 디텍토리에 들어간다. 그리고 다음 명령어를 입력한다.
라고 입력하여 저장되어 있는 디텍토리에 들어간다. 그리고 다음 명령어를 입력한다.


$ cc 파일이름(파일이름이 test.c라면 cc test.c라고 입력한다)
  ~$ cc 파일이름(파일이름이 test.c라면 cc test.c라고 입력한다)
</syntaxhighlight>
 
이렇게 할 경우 a.out이라는 파일이 생성되었을 것이다. 이것이 바로 컴파일된 파일이다.
이렇게 할 경우 a.out이라는 파일이 생성되었을 것이다. 이것이 바로 컴파일된 파일이다.
마지막으로
마지막으로
<syntaxhighlight lang=console>
 
$ ./a.out
  ~$ ./a.out
</syntaxhighlight>


이라고 터미널에 입력하면 컴파일된 파일을 실행할 수 있다. 만약 gcc가 설치되어 있다면 cc 대신에 gcc라는 명령어를 사용할 수도 있다. 차이점은 cc는 유닉스 시스템에 기본으로 내장되어 있는 컴파일러이고, gcc는 별도로 설치하는 컴파일러라는 것이다. 업계에서는 gcc의 사용 빈도가 높으므로, gcc에 익숙해지는 게 좋다.
이라고 터미널에 입력하면 컴파일된 파일을 실행할 수 있다. 만약 gcc가 설치되어 있다면 cc 대신에 gcc라는 명령어를 사용할 수도 있다. 차이점은 cc는 유닉스 시스템에 기본으로 내장되어 있는 컴파일러이고, gcc는 별도로 설치하는 컴파일러라는 것이다. 업계에서는 gcc의 사용 빈도가 높으므로, gcc에 익숙해지는 게 좋다.
<syntaxhighlight lang=console>
 
$ gcc test.c
  ~$ gcc test.c
</syntaxhighlight>
라는 명렁어를 사용하면, cc를 썻을 때 처럼 a.out이라는 이름의 파일이 생성된다. 만약 a.out이라는 파일 이름이 마음에 들지 않는다면
라는 명렁어를 사용하면, cc를 썻을 때 처럼 a.out이라는 이름의 파일이 생성된다. 만약 a.out이라는 파일 이름이 마음에 들지 않는다면
<syntaxhighlight lang=console>
  ~$ gcc -o result test.c
$ gcc -o result test.c
</syntaxhighlight>
라는 명령어를 쳐보자. 이렇게하면 이름이 result인 파일이 생성된다.<!-- 또한
라는 명령어를 쳐보자. 이렇게하면 이름이 result인 파일이 생성된다.<!-- 또한
$ gcc -ansi test.c
  ~$ gcc -ansi test.c
혹은
혹은
$ gcc -ansi -o result test.c
  ~$ gcc -ansi -o result test.c
라는 명령어도 알아두는 것이 좋다. 이렇게하면 ANSI 표준으로 컴파일된다. 쉽게 말하자면 옛날 표준으로 컴파일이 된다는 것인데, C언어는 특성상 개발자들이 옛 표준인 ANSI를 매우매우매우 사랑하므로 이왕이면 ANSI 표준에 맞게 코딩하는 습관을 기르는 게 좋다. 그러므로 ANSI 표준으로 컴파일해주는 이 명령어를 애용하여서 평소에 익혀두자.
라는 명령어도 알아두는 것이 좋다. 이렇게하면 ANSI 표준으로 컴파일된다. 쉽게 말하자면 옛날 표준으로 컴파일이 된다는 것인데, C언어는 특성상 개발자들이 옛 표준인 ANSI를 매우매우매우 사랑하므로 이왕이면 ANSI 표준에 맞게 코딩하는 습관을 기르는 게 좋다. 그러므로 ANSI 표준으로 컴파일해주는 이 명령어를 애용하여서 평소에 익혀두자.
-->
-->
142번째 줄: 134번째 줄:
자 Hello World를 출력해보신 입문자분들! 무슨 뜻인지도 모르고 코드를 쳤을 거라 생각한다. 이제 코드를 한줄 한줄 해석해 보겠다.
자 Hello World를 출력해보신 입문자분들! 무슨 뜻인지도 모르고 코드를 쳤을 거라 생각한다. 이제 코드를 한줄 한줄 해석해 보겠다.


자 우선 프로그램을 만들때 쓰일 부품(함수나 기타 등등...)들이 무엇인지 알아야 컴파일러에게 알려줘야 한다. 초보적인 텍스트를 출력하는 것이므로 많은 부품은 필요하지 않다. 기본적인 부품들이 들어 있는 파일을 포함시켜야 한다. 따라서 다음과 같은 문장을 써준다. #include는 컴파일러에 포함되어 있는 전처리기가 컴파일하기 전에 필요한 라이브러리들을 포함해주는 역할을 한다. 쉽게 말해 필요한 모든 참고도서를 포함한다고 생각해도 된다.
자 우선 프로그램을 만들때 쓰일 부품(함수나 기타등등...)들이 무엇인지 알아야 컴파일러에게 알려줘야 한다. 초보적인 텍스트를 출력하는 것이므로 많은 부품은 필요하지 않다. 기본적인 부품들이 들어 있는 파일을 포함시켜야 한다. 따라서 다음과 같은 문장을 썻다.


<syntaxhighlight lang=c>
<source lang=c>
#include <stdio.h>
#include <stdio.h>
</syntaxhighlight>
</source>
   
   
그 다음, 프로그램이 시작되는 지점을 알려줘야 한다. C언어에서는 프로그램이 시작할 때  main이라는 함수에서 시작하게 된다. 아직 프로그래밍에서의 함수에 대해서 배우지는 않았겠지만, 수학의 함수는 알고 있을 것이다.
그 다음, 프로그램이 시작되는 지점을 알려줘야 한다. C언어에서는 프로그램이 시작할 때  main이라는 함수에서 시작하게 된다. 아직 프로그래밍에서의 함수에 대해서 배우지는 않았겠지만, 수학의 함수는 알고 있을 것이다.
<syntaxhighlight lang=c>
<source lang=c>
int main(void)
int main(void)
{
{
    return 0;
return 0;
}
}
</syntaxhighlight>
</source>
함수의 중괄호'''{'''와 '''}''' 사이는 해당 함수가 어떤 동작을 하는 지 정의하는 곳이다. 또한 '''('''와 ''')''' 안에는 함수의 입력값이 어떠한 형태(자료형, Data Type)인지를 명시하는 곳이다. 함수의 이름 앞에 놓여 있는 단어는 함수의 출력값이 어떠한 형태인지를 명시하는 곳이다. 따라서 int main(void)는 출력이 int인<ref>int가 정확히 어떤 뜻인지는 아래에 나온다.</ref> 형태이고, 입력값이 없는(void) 함수이며, 중괄호 안에 적혀 있는 대로 함수값이 정의됨을 알 수 있다.
함수의 중괄호'''{'''와 '''}''' 사이는 해당 함수가 어떤 동작을 하는 지 정의하는 곳이다. 또한 '''('''와 ''')''' 안에는 함수의 입력값이 어떠한 형태(자료형, Data Type)인지를 명시하는 곳이다. 함수의 이름 앞에 놓여 있는 단어는 함수의 출력값이 어떠한 형태인지를 명시하는 곳이다. 따라서 int main(void)는 출력이 int인<ref>int가 정확히 어떤 뜻인지는 아래에 나온다.</ref> 형태이고, 입력값이 없는(void) 함수이며, 중괄호 안에 적혀 있는 대로 함수값이 정의됨을 알 수 있다.
자 이제 Hello, World를 출력하는 코드를 main함수의 정의 부분(중괄호)에 넣어주면 된다. Hello, World를 출력하는 코드는 다음과 같다.
자 이제 Hello, World를 출력하는 코드를 main함수의 정의 부분(중괄호)에 넣어주면 된다. Hello, World를 출력하는 코드는 다음과 같다.
<syntaxhighlight lang=c>
<source lang=c>
printf("Hello, World!\n");
printf("Hello, World!\n");
</syntaxhighlight>
</source>
printf라는 것 또한 함수이다. 소괄호 안에 쌍따옴표로 둘러 쌓여 있는 Hello, World!\n를 볼 수 있다. 함수를 선언하거나 정의할 때 소괄호는 '입력의 형태'를 뜻하지만, 여기에서처럼 함수를 '사용'(호출이라고 한다)할 때는 '입력값'을 뜻한다. 즉 "Hello, World\n"가<ref>C언어에서 쌍따음표는 '문장(문자열)'을 뜻한다. 그리고 '\n'은 '개행'을 뜻하는 문자로 취급된다. 또한 \n은 한 글자로 취급되므로 주의하자.</ref> printf함수의 입력값으로서 들어간 것이다.
printf라는 것 또한 함수이다. 소괄호 안에 쌍따옴표로 둘러 쌓여 있는 Hello, World!\n를 볼 수 있다. 함수를 선언하거나 정의할 때 소괄호는 '입력의 형태'를 뜻하지만, 여기에서처럼 함수를 '사용'(호출이라고 한다)할 때는 '입력값'을 뜻한다. 즉 "Hello, World\n"가<ref>C언어에서 쌍따음표는 '문장(문자열)'을 뜻한다. 그리고 '\n'은 '개행'을 뜻하는 문자로 취급된다. 또한 \n은 한 글자로 취급되므로 주의하자.</ref> printf함수의 입력값으로서 들어간 것이다.
또한 C언어에서는 코드 한문장 한문장을 ;으로 끝내게 되어 있다.
또한 C언어에서는 코드 한문장 한문장을 ;으로 끝내게 되어 있다.
따라서 printf("Hello, World!\n")을 한뒤 해당 명령이 끝났다는 뜻에서 ;를 붙여 준다.
따라서 printf("Hello, World!\n")을 한뒤 해당 명령이 끝났다는 뜻에서 ;를 붙여 준다.
앞에서 말한 #include로 필요한 참고도서를 포함하지 않았다면 컴파일러가 printf가 무슨 함수인지를 몰라 오류가 난다. <nowiki><stdio.h></nowiki> 꺽쇠괄호 안에 써있는 stdio.h 파일에 printf, scanf같은 함수가 어떤 것인지 적혀있는데 stdio.h가 빠지면 이 함수들이 작동하지 않게 된다.<ref>함수마다 포함시켜야 하는 라이브러리가 다른데 나중에 깊게 파헤쳐보자.</ref>


=== 변수 ===
=== 변수 ===
==== 변수가 뭔가요? ====
==== 변수가 뭔가요? ====
==== 변수명으로 사용할 수 없는 이름들? ====
==== 변수명으로 사용할 수 없는 이름들? ====
C언어에서 특별한 의미를 갖고 있어서 변수 이름으로 사용할 수 없는 이름들이 있습니다. 이것을 '''식별자'''(키워드)라고 합니다.
C언어에서 특별한 의미를 갖고 있어서 변수 이름으로 사용할 수 없는 이름들이 있습니다. 이것을 '''식별자'''(키워드)라고 합니다.  
* auto
* auto
* break
* break
242번째 줄: 233번째 줄:
=== 배열 ===
=== 배열 ===


예를 들어 30개의 문자를 입력받는 코드를 만들어야 한다고 칠때, char q,w,e,r,t,y,u...... 같은 선언을 일일이 하려면 <del>손가락이</del>귀찮지 않나요?<del>뭐 이렇게 하고 싶을때도 있겠지만 말이죠....</del> 그럴때는
예를 들어 30개의 문자를 입력받는 코드를 만들어야 한다고 칠때, char q,w,e,r,t,y,u...... 같은 선언을 일일이 하려면 <del>손가락이</del>귀찮지 않나요?<del>뭐 이렇게 하고싶을때도 있겠지만 말이죠....</del> 그럴때는
<syntaxhighlight lang=c>
<source lang=c>
int i[30];//정수
int i[30];//정수
</syntaxhighlight>
</source>


또는 (int는 숫자(정수)를 사용할 때)
또는 (int는 숫자(정수)를 사용할 때)


<syntaxhighlight lang=c>
<source lang=c>
char c[30];//문자
char c[30];//문자
</syntaxhighlight>
</source>


을 쓰면 쉽게 할 수 있어요.(꼭 i나 c가 아니어도 내가 하고 싶은걸로 하면 돼요.)
을 쓰면 쉽게 할 수 있어요.(꼭 i나 c가 아니어도 내가 하고 싶은걸로 하면 돼요.)


<syntaxhighlight lang=c>
int i[30];
</syntaxhighlight>
이런식으로 배열을 선언해주면 30개의 i변수를 한번에 선언해주게 됩니다. 첫 번째 i변수는 i[0]이고 다섯 번째 i변수는 i[4], 30번째 i변수는 i[29] 이런식으로 변수가 생성되는거죠 <del>30번째가 변수는 i[30]가 아닙니다!</del> 이런식으로 변수 번호를 혼동하면 참조할 때 존재하지 않는 변수가 참조되어 쓰레기 값이 나옵니다. <del>ex)-38488323(의미없는 숫자)</del>


[[추가 바람]]
[[추가 바람]]
265번째 줄: 252번째 줄:
=== printf가 뭐죠? ===
=== printf가 뭐죠? ===
====형식====
====형식====
[[파일:Printf.svg|Printf]]
[[File:Printf.svg|Printf]]


printf(const char *format, ...);
printf(const char *format, ...);
325번째 줄: 312번째 줄:
: 점으로 시작하며, 숫자 값이 들어간다. 해당 포맷 스트링의 값이 표시될 최대한의 길이를 지정하는데 쓰인다. 말은 이렇긴 한데, 보통 부동소수점 형의 경우 자릿수를 지정하는데 쓰이며, 문자열 형의 경우 이 길이까지만 표시하라는 지정자가 된다.
: 점으로 시작하며, 숫자 값이 들어간다. 해당 포맷 스트링의 값이 표시될 최대한의 길이를 지정하는데 쓰인다. 말은 이렇긴 한데, 보통 부동소수점 형의 경우 자릿수를 지정하는데 쓰이며, 문자열 형의 경우 이 길이까지만 표시하라는 지정자가 된다.
: 위에 쓰인 표시길이와 정확도는 각 포맷 스트링의 값이 표시될 최소/최대치를 지정하는 것인데, 이를 포맷 스트링에서 직접 입력하지 않고, 인자로 받아 쓰는 방법도 존재한다. *를 쓰면 인자에서 값을 읽어 그 길이를 사용하게 된다.
: 위에 쓰인 표시길이와 정확도는 각 포맷 스트링의 값이 표시될 최소/최대치를 지정하는 것인데, 이를 포맷 스트링에서 직접 입력하지 않고, 인자로 받아 쓰는 방법도 존재한다. *를 쓰면 인자에서 값을 읽어 그 길이를 사용하게 된다.
<syntaxhighlight lang="c">
<source lang="c">
printf("%*d",  5, 123); // "  123"을 출력한다.
printf("%*d",  5, 123); // "  123"을 출력한다.
printf("%.*s", 5, "abcdefg"); // "abcde"를 출력한다.
printf("%.*s", 5, "abcdefg"); // "abcde"를 출력한다.
</syntaxhighlight>
</source>
; 데이터길이 (Length)
; 데이터길이 (Length)
: 인자의 길이를 추정하도록 도와주는 옵션이다. 보통 캐스팅을 하고 쓰지 않으면 읽을 바이트 수를 오인해서 결과를 잘못 표시할 수 있는데, 이 포맷 스트링을 쓰는 경우 길이를 강제하기 때문에 사실상 printf 내에서 캐스팅과 같은 효과를 낸다.
: 인자의 길이를 추정하도록 도와주는 옵션이다. 보통 캐스팅을 하고 쓰지 않으면 읽을 바이트 수를 오인해서 결과를 잘못 표시할 수 있는데, 이 포맷 스트링을 쓰는 경우 길이를 강제하기 때문에 사실상 printf 내에서 캐스팅과 같은 효과를 낸다.
410번째 줄: 397번째 줄:
====사용 예====
====사용 예====
=====소스=====
=====소스=====
<syntaxhighlight lang='c'>
<source lang='c'>
#include <stdio.h>
#include <stdio.h>
int main(void)
int main(void)
{
{
    printf("%d\n",10);
printf("%d\n",10);
    printf("%o\n",10);
printf("%o\n",10);
    printf("%x\n",14);
printf("%x\n",14);
    printf("%X\n",14);
printf("%X\n",14);
    printf("%c\n",'a');
printf("%c\n",'a');
    printf("%c\n",96);
printf("%c\n",96);
    printf("%s\n","hello world");
printf("%s\n","hello world");
    return 0;
return 0;
}
}
</syntaxhighlight>
</source>


=====결과=====
=====결과=====
464번째 줄: 451번째 줄:
# '''비트 연산자'''
# '''비트 연산자'''
#: 값을 비트 단위로 조작한다. 일반적인 경우에는 쓸 일이 많지 않으며, 비트 단위로 무언가를 하는 경우(하드웨어에 무슨 신호를 보낸다거나) 등에 쓰인다.
#: 값을 비트 단위로 조작한다. 일반적인 경우에는 쓸 일이 많지 않으며, 비트 단위로 무언가를 하는 경우(하드웨어에 무슨 신호를 보낸다거나) 등에 쓰인다.
#:* <code><<</code> : 왼쪽 {{|Shift}}
#:* <code><<</code> : 왼쪽 {{키눌림|Shift}}
#:* <code>>></code> : 오른쪽 {{|Shift}}
#:* <code>>></code> : 오른쪽 {{키눌림|Shift}}
#:* <code>~</code> : 비트 NOT. 비트를 반전시킨다. 단항 연산이다.
#:* <code>~</code> : 비트 NOT. 비트를 반전시킨다. 단항 연산이다.
#:* <code>&</code> : 비트 AND
#:* <code>&</code> : 비트 AND
475번째 줄: 462번째 줄:
#: 다음은 복합 대입 연산자라고 한다. 기존 값에 산술 연산이나 비트 연산을 한 결과를 대입하고 싶을 때 사용한다.
#: 다음은 복합 대입 연산자라고 한다. 기존 값에 산술 연산이나 비트 연산을 한 결과를 대입하고 싶을 때 사용한다.
#:* <code>+=</code>, <code>-=</code>, <code>*=</code>, <code>/=</code>, <code>&=</code> : 기존값에 더해서/빼서/곱해서/나눠서/나머지를 대입.
#:* <code>+=</code>, <code>-=</code>, <code>*=</code>, <code>/=</code>, <code>&=</code> : 기존값에 더해서/빼서/곱해서/나눠서/나머지를 대입.
#:* <code>&=</code>, <code>|=</code>, <code>^=</code>, <code><<=</code>, <code>>>=</code> : 기존값에 AND/OR/XOR/왼쪽 {{|Shift}}/오른쪽 {{|Shift}} 해서 대입.
#:* <code>&=</code>, <code>|=</code>, <code>^=</code>, <code><<=</code>, <code>>>=</code> : 기존값에 AND/OR/XOR/왼쪽 {{키눌림|Shift}}/오른쪽 {{키눌림|Shift}} 해서 대입.
#: 뭔가 복잡해 보이지만, 사실상 코드를 짧게 줄여 쓰기 위한 것들이다. 예를 들어 <syntaxhighlight lang="C">a += b;</syntaxhighlight> 는 <syntaxhighlight lang="C">a = a + b;</syntaxhighlight>의 줄임 형식이다.
#: 뭔가 복잡해 보이지만, 사실상 코드를 짧게 줄여 쓰기 위한 것들이다. 예를 들어 <source lang="C">a += b;</source> 는 <source lang="C">a = a + b;</source>의 줄임 형식이다.
# '''참조 연산자'''
# '''참조 연산자'''
#: 값 그 자체가 아니라, 값이 가리키고 있는 위치를 '참조'하는 연산자이다. 아직 설명 안 된 부분도 있으니까, 잘 모르겠다면 지금은 '이런 것도 있구나' 하고 넘어가도 좋다.
#: 값 그 자체가 아니라, 값이 가리키고 있는 위치를 '참조'하는 연산자이다. 아직 설명 안 된 부분도 있으니까, 잘 모르겠다면 지금은 '이런 것도 있구나' 하고 넘어가도 좋다.
491번째 줄: 478번째 줄:
# '''괄호'''. <del>최종보스</del> 괄호가 쳐져 있으면 무조건 먼저 계산한다. <del>당연하잖아.</del> 괄호는 '이걸 먼저 계산해라'고 알려주는 역할을 한다.
# '''괄호'''. <del>최종보스</del> 괄호가 쳐져 있으면 무조건 먼저 계산한다. <del>당연하잖아.</del> 괄호는 '이걸 먼저 계산해라'고 알려주는 역할을 한다.
# <code>++</code>(변수 뒤), <code>--</code>(변수 뒤), <code>[]</code>(배열 첨자), <code>.</code>(구조체 멤버), <code>-></code>(포인터 구조체 멤버), <code>()</code>(함수 호출. printf()할 때의 그 괄호다.)
# <code>++</code>(변수 뒤), <code>--</code>(변수 뒤), <code>[]</code>(배열 첨자), <code>.</code>(구조체 멤버), <code>-></code>(포인터 구조체 멤버), <code>()</code>(함수 호출. printf()할 때의 그 괄호다.)
# <code>++</code>(변수 앞), <code>--</code>(변수 앞), <code>+</code>(양수 표기), <code>-</code>(음수 표기), <code>!</code>(논리 NOT), <code>~</code>(비트 NOT), <code>*</code>(포인터 참조), <code>&</code>(값의 주소).<br />바로 밑에서 설명할 '''형변환'''도 이 레벨이다. 이 레벨의 연산자들은 전부 단항 연산자들이며, 오른쪽에서 왼쪽으로 계산된다는 특징이 있다. <code>++a</code>나 <code>!a</code> 처럼.
# <code>++</code>(변수 앞), <code>--</code>(변수 앞), <code>+</code>(양수 표기), <code>-</code>(음수 표기), <code>!</code>(논리 NOT), <code>~</code>(비트 NOT), <code>*</code>(포인터 참조), <code>&</code>(값의 주소).<br>바로 밑에서 설명할 '''형변환'''도 이 레벨이다. 이 레벨의 연산자들은 전부 단항 연산자들이며, 오른쪽에서 왼쪽으로 계산된다는 특징이 있다. <code>++a</code>나 <code>!a</code> 처럼.
# <code>*</code>(곱하기), <code>/</code>(나누기), <code>%</code>(나머지) <del>신난다 드디어 아는 게 나왔어!</del>
# <code>*</code>(곱하기), <code>/</code>(나누기), <code>%</code>(나머지) <del>신난다 드디어 아는 게 나왔어!</del>
# <code>+</code>(더하기), <code>-</code>(빼기)
# <code>+</code>(더하기), <code>-</code>(빼기)
# <code><<</code>(왼쪽 {{|Shift}}), <code>>></code>(오른쪽 {{|Shift}})
# <code><<</code>(왼쪽 {{키눌림|Shift}}), <code>>></code>(오른쪽 {{키눌림|Shift}})
# 크기를 비교할 때 쓰는 논리 연산자들. <code><</code>, <code><=</code>, <code>></code>, <code>>=</code>
# 크기를 비교할 때 쓰는 논리 연산자들. <code><</code>, <code><=</code>, <code>></code>, <code>>=</code>
# 같냐 다르냐를 비교하는 논리 연산자들. <code>==</code>(같다), <code>!=</code>(다르다)
# 같냐 다르냐를 비교하는 논리 연산자들. <code>==</code>(같다), <code>!=</code>(다르다)
508번째 줄: 495번째 줄:
==== 주의점 ====
==== 주의점 ====
우선 다음 코드를 봐 보자.
우선 다음 코드를 봐 보자.
<syntaxhighlight lang="C">
<source lang="C">
int a = 9; int b = 2; double res; //앞의 두개의 변수는 정수형, 나머지 하나는 실수형 변수.
int a = 9; int b = 2; double res; //앞의 두개의 변수는 정수형, 나머지 하나는 실수형 변수.
res = a / b;
res = a / b;
printf("res = %f", res);
printf("res = %f", res);
</syntaxhighlight>
</source>
자, 그럼 res의 출력값은?
자, 그럼 res의 출력값은?


524번째 줄: 511번째 줄:


하지만 위의 저 코드를 만든 사람은 4.5가 나오기를 기대하고 만들었을 것이다. 그럼 어떻게 해야 4.5가 나오게 할 수 있을까? 해답은 '''형변환'''을 쓰는 것이다. 변수 앞에, 괄호를 치고 자료형을 쓰면 그 변수를 해당 자료형으로 임시로 바꿔준다.
하지만 위의 저 코드를 만든 사람은 4.5가 나오기를 기대하고 만들었을 것이다. 그럼 어떻게 해야 4.5가 나오게 할 수 있을까? 해답은 '''형변환'''을 쓰는 것이다. 변수 앞에, 괄호를 치고 자료형을 쓰면 그 변수를 해당 자료형으로 임시로 바꿔준다.
<syntaxhighlight lang="C">
<source lang="C">
int a = 9; int b = 2; double res;  
int a = 9; int b = 2; double res;  
res = (double) a / b; //a를 일시적으로 실수형으로 인식하도록 만든다.
res = (double) a / b; //a를 일시적으로 실수형으로 인식하도록 만든다.
printf("res = %f", res);
printf("res = %f", res);
</syntaxhighlight>
</source>
위의 우선순위 리스트에서, 2번째 레벨에 있던 형변환을 사용한다. 나누기는 레벨 4니까, 9 나누기 2를 하기 전에 먼저 9를 9.0으로 바꿔주는 것이다. 이번에도 마찬가지로 컴퓨터의 사고 방식을 들여다보자.
위의 우선순위 리스트에서, 2번째 레벨에 있던 형변환을 사용한다. 나누기는 레벨 4니까, 9 나누기 2를 하기 전에 먼저 9를 9.0으로 바꿔주는 것이다. 이번에도 마찬가지로 컴퓨터의 사고 방식을 들여다보자.
# 먼저, 9를 9.0으로 바꾼다.
# 먼저, 9를 9.0으로 바꾼다.
540번째 줄: 527번째 줄:


====if-else문====
====if-else문====
<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (조건)
if (조건)
{
{
    내용 1
내용 1
}
}
else
else
{
{
    내용 2
내용 2
}
}
</syntaxhighlight>
</source>


조건의 내용이 참이면 내용 1을, 거짓이면 내용 2를 실행한다.
조건의 내용이 참이면 내용 1을, 거짓이면 내용 2를 실행한다.
555번째 줄: 542번째 줄:
else는 없어도 된다. 예를 들어,
else는 없어도 된다. 예를 들어,


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (조건)
if (조건)
{
{
    내용 1
내용 1
}
}
</syntaxhighlight>
</source>


조건이 참이면 내용 1을 실행하고 거짓이면 실행하지 않고 넘어간다.
조건이 참이면 내용 1을 실행하고 거짓이면 실행하지 않고 넘어간다.


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (a >= 0)
if (a >= 0)
{
{
573번째 줄: 560번째 줄:
     printf("%d", -1 * a);
     printf("%d", -1 * a);
}
}
</syntaxhighlight>
</source>


만약 a가 0 이상이라면 그대로 출력하고 미만이라면 -1을 곱해서 출력하라는 의미이다.
만약 a가 0 이상이라면 그대로 출력하고 미만이라면 -1을 곱해서 출력하라는 의미이다.
또한, {}를 생략해도 된다.
또한, {}를 생략해도 된다.


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (a >= 0)
if (a >= 0)
     printf("%d", a);
     printf("%d", a);
else
else
     printf("%d", -1 * a);
     printf("%d", -1 * a);
</syntaxhighlight>
</source>


즉, 이렇게 써도 된다. 하지만 {}를 생략할 경우 코드 한 줄만 if-else문의 범위에 들어가진다.
즉, 이렇게 써도 된다. 하지만 {}를 생략할 경우 코드 한 줄만 if-else문의 범위에 들어가진다.


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (a >= 0)
if (a >= 0)
     printf("%d", a);
     printf("%d", a);
593번째 줄: 580번째 줄:
     a = -1 * a;
     a = -1 * a;
printf("%d", a);
printf("%d", a);
</syntaxhighlight>
</source>


이렇게 작성하면, 조건이 거짓일때 a = -1 * a;만을 실행하고 빠져나온 다음 printf("%d", a);를 실행한다. 조건이 참일때는 printf("%d", a);를 실행한 다음 빠져나온 다음 밑의 printf("%d", a);를 실행하게 된다. 이렇게 꼬일 수도 있으니 {}를 생략할 때에는 가독성을 위해 들여쓰기를 생활화하자.
이렇게 작성하면, 조건이 거짓일때 a = -1 * a;만을 실행하고 빠져나온 다음 printf("%d", a);를 실행한다. 조건이 참일때는 printf("%d", a);를 실행한 다음 빠져나온 다음 밑의 printf("%d", a);를 실행하게 된다. 이렇게 꼬일 수도 있으니 {}를 생략할 때에는 가독성을 위해 들여쓰기를 생활화하자.
599번째 줄: 586번째 줄:
if-else문을 중첩해서 사용할 수도 있다.
if-else문을 중첩해서 사용할 수도 있다.


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (조건 1)
if (조건 1)
{
{
    내용 1
내용 1
}
}
else
else
608번째 줄: 595번째 줄:
     if (조건 2)
     if (조건 2)
     {
     {
        내용 2
    내용 2
     }
     }
     else
     else
     {
     {
        내용 3
    내용 3
     }
     }
}
}
</syntaxhighlight>
</source>


이 경우, 조건 1이 참이면 내용 1을 실행한다. 거짓이면 안으로 들어가고, 조건 2가 참이면 내용 2를, 거짓이면 내용 3을 실행한다.
이 경우, 조건 1이 참이면 내용 1을 실행한다. 거짓이면 안으로 들어가고, 조건 2가 참이면 내용 2를, 거짓이면 내용 3을 실행한다.


<syntaxhighlight lang = 'c'>
<source lang = 'c'>
if (조건 1)
if (조건 1)
{
{
    내용 1
내용 1
}
}
else if (조건 2)
else if (조건 2)
{
{
    내용 2
내용 2
}
}
else
else
{
{
    내용 3
내용 3
}
}
</syntaxhighlight>
</source>


{}를 생략해서 이렇게 작성할 수도 있다.
{}를 생략해서 이렇게 작성할 수도 있다.
639번째 줄: 626번째 줄:
여러 조건들중 하나를 선택할 때 사용한다.
여러 조건들중 하나를 선택할 때 사용한다.
=====형식=====
=====형식=====
<syntaxhighlight lang=C>
<source lang=C>
switch(수식)
switch(수식)
{
{
    case 0 :  //0일때 실행
      case 0 :  //0일때 실행
    case 1 :  //1일때 실행
      case 1 :  //1일때 실행
    case 2 :  //2일때 실행
      case 2 :  //2일때 실행
    case 3 :  //3일때 실행
      case 3 :  //3일때 실행
    case 4 :  //4일때 실행
      case 4 :  //4일때 실행
    default : //아무것도 아닐때 실행
      default : //아무것도 아닐때 실행
}
}
</syntaxhighlight>
</source>


수식은 정수, 실수,음수 전부 가능하다.
수식은 정수, 실수,음수 전부 가능하다.
655번째 줄: 642번째 줄:
default 의경우 있어도 되고 없어도 된다.
default 의경우 있어도 되고 없어도 된다.
=====소스=====
=====소스=====
<syntaxhighlight lang=c>
<source lang=c>
switch(num)
switch(num)
{
{
    case 0 : printf("num = 0");
      case 0 : printf("num = 0");
    case 1 : printf("num = 1");
      case 1 : printf("num = 1");
    case 2 : printf("num = 2");
      case 2 : printf("num = 2");
    case 3 : printf("num = 3");
      case 3 : printf("num = 3");
    case 4 : printf("num = 4");
      case 4 : printf("num = 4");
    default : printf("맞는 수가 없습니다" );
      default : printf("맞는 수가 없습니다" );
}
}
</syntaxhighlight>
</source>


=====결과=====
=====결과=====
679번째 줄: 666번째 줄:
만약 한 가지만 실행하려면 break문과 함께 써주면 된다.
만약 한 가지만 실행하려면 break문과 함께 써주면 된다.
=====소스=====
=====소스=====
<syntaxhighlight lang=c>
<source lang=c>
switch(num)
switch(num)
{
{
    case 0 : printf("num = 0");break;
      case 0 : printf("num = 0");break;
    case 1 : printf("num = 1");break;
      case 1 : printf("num = 1");break;
    case 2 : printf("num = 2");break;
      case 2 : printf("num = 2");break;
    ase 3 : printf("num = 3");break;
      case 3 : printf("num = 3");break;
    case 4 : printf("num = 4");break;
      case 4 : printf("num = 4");break;
    default : printf("맞는 수가 없습니다" );
      default : printf("맞는 수가 없습니다" );
}
}
</syntaxhighlight>
</source>


=====결과=====
=====결과=====
704번째 줄: 691번째 줄:


====while문====
====while문====
<syntaxhighlight lang=c>
<source lang=c>
while (조건문)
while (조건문)
{
{
    문장
문장
}
}
</syntaxhighlight>
</source>


while문을 만나면 먼저 조건문을 검사한다. 조건문의 내용이 참이면 문장을 실행하고, 거짓이면 실행하지 않고 넘어간다. 문장의 내용을 모두 실행한 뒤에 다시 조건문을 검사한다. 계속 반복하다가 조건문이 거짓이 되면 빠져나온다. 주의할 점은 실수로 코드를 잘못짜서 조건문의 변수가 계속 바뀌지 않는다면 영원히 반복되어 <del>무한루프</del> 조건문을 잘 설정하는게 중요하다.
while문을 만나면 먼저 조건문을 검사한다. 조건문의 내용이 참이면 문장을 실행하고, 거짓이면 실행하지 않고 넘어간다. 문장의 내용을 모두 실행한 뒤에 다시 조건문을 검사한다. 계속 반복하다가 조건문이 거짓이 되면 빠져나온다.


====for문====
====for문====
<syntaxhighlight lang=c>
<source lang=c>
for (초기식; 조건식; 변환식)
for (초기식; 조건식; 변환식)
{
{
    문장
문장
}
}
</syntaxhighlight>
</source>


for문을 만나면 먼저 초기식을 실행한다. 조건식이 참이면 문장을 실행하고 거짓이면 실행하지 않고 넘어간다. 문장을 실행한 뒤, 변환식을 실행한 다음 조건식을 검사하고 참이면 실행, 거짓이면 넘어가기를 조건식이 거짓이 될 때까지 반복한다. 식들은 생략할 수 있지만 세미콜론은 생략할 수 없다.
for문을 만나면 먼저 초기식을 실행한다. 조건식이 참이면 문장을 실행하고 거짓이면 실행하지 않고 넘어간다. 문장을 실행한 뒤, 변환식을 실행한 다음 조건식을 검사하고 참이면 실행, 거짓이면 넘어가기를 조건식이 거짓이 될 때까지 반복한다. 식들은 생략할 수 있지만 세미콜론은 생략할 수 없다.


<syntaxhighlight lang=c>
<source lang=c>
for (초기식; ; 변환식)
for (초기식; ; 변환식)
{
{
    문장
문장
}
}
</syntaxhighlight>
</source>


조건식을 생략하면 이런 모습이 된다. 모든 식을 다 비우는 경우는 자동으로 무한 루프가 된다.<ref>보통 많이 쓰는 while(1)의 경우 컴파일러가 최적화해주지 않으면 1을 비교하면서 돌아버리기 때문에 비교 연산이 전혀 없이 순수하게 루프만 도는 for (;;)를 선호하는 사람들도 있다.</ref>
조건식을 생략하면 이런 모습이 된다. 모든 식을 다 비우는 경우는 자동으로 무한 루프가 된다.<ref>보통 많이 쓰는 while(1)의 경우 컴파일러가 최적화해주지 않으면 1을 비교하면서 돌아버리기 때문에 비교 연산이 전혀 없이 순수하게 루프만 도는 for (;;)를 선호하는 사람들도 있다.</ref>


<syntaxhighlight lang=c>
<source lang=c>
for ( ; ; )
for ( ; ; )
{
{
// Infinite loops
// Infinite loops
}
}
</syntaxhighlight>
</source>


BASIC 등 여타 언어의 for문보다 덜 직관적이라고 생각할 수 있는데, 오히려 논리적으로 간명하고 확장성이 뛰어난 면이 있다. 예를 들어 ‘1/1 + 1/2 + … + 1/N이 100을 넘는 최초의 N’과 같은 것을 찾을 수 있다.
BASIC 등 여타 언어의 for문보다 덜 직관적이라고 생각할 수 있는데, 오히려 논리적으로 간명하고 확장성이 뛰어난 면이 있다. 예를 들어 ‘1/1 + 1/2 + … + 1/N이 100을 넘는 최초의 N’과 같은 것을 찾을 수 있다.


머릿속에서 다음 코드와 같다고 생각해도 된다.
머릿속에서 다음 코드와 같다고 생각해도 된다.
<syntaxhighlight lang=c>
<source lang=c>
초기식
초기식
while (조건식)
while (조건식)
{
{
    문장
문장
    변환식
변환식
}
}
</syntaxhighlight>
</source>


====do-while문====
====do-while문====
<syntaxhighlight lang=c>
<source lang=c>
do{
do{
    문장
문장
}while (조건식);
}while (조건식);
</syntaxhighlight>
</source>


while문과 유사하지만 조건식을 먼저 검사하지 않고 중괄호 안의 내용을 먼저 검사한 뒤에 조건식을 검사한다.그러나 최초 한번은 반드시 실행되는 만큼 꼭 필요할 때 사용해야 한다.
while문과 유사하지만 조건식을 먼저 검사하지 않고 중괄호 안의 내용을 먼저 검사한 뒤에 조건식을 검사한다.그러나 최초 한번은 반드시 실행되는 만큼 그리 권장하지는 않는다.


==== break ====
==== break ====
현재 실행하고 있는 반복문을 빠져나온다. 반복문이 여러 개 중첩되어 있으면 가장 가까운 반복문을 하나 빠져나온다.
현재 실행하고 있는 반복문을 빠져나온다. 반복문이 여러 개 중첩되어 있으면 가장 가까운 반복문을 하나 빠져나온다.


<syntaxhighlight lang = "c">
<source lang = "c">
while (true)
while (true)
{
{
    내용 1
내용 1
while (true)
while (true)
{
{
    내용 2
내용 2
    break;
break;
}
}
}
}
</syntaxhighlight>
</source>


내용 1을 실행한 다음 while문 안으로 들어가 내용 2를 실행, 바로 빠져나와 다시 내용 1을 실행, 내용 2를 실행을 무한 반복한다.
내용 1을 실행한 다음 while문 안으로 들어가 내용 2를 실행, 바로 빠져나와 다시 내용 1을 실행, 내용 2를 실행을 무한 반복한다.
780번째 줄: 767번째 줄:
보통 C 프로그래밍을 시작한 초보자가 가장 이해하고 배우기 힘들어하는 부분. <s>터닝포인터</s><ref>취소선을 표시했지만 정말 이 부분에서 C언어를 포기하는 사람들이 급증한다. 과장 조금 보태서 포인터를 완벽하게 이해한다면 C언어를 거의 다 이해했다고 할 수 있을 정도이다.</ref>
보통 C 프로그래밍을 시작한 초보자가 가장 이해하고 배우기 힘들어하는 부분. <s>터닝포인터</s><ref>취소선을 표시했지만 정말 이 부분에서 C언어를 포기하는 사람들이 급증한다. 과장 조금 보태서 포인터를 완벽하게 이해한다면 C언어를 거의 다 이해했다고 할 수 있을 정도이다.</ref>


먼저 '''포인터'''(Pointer)라는 개념부터 설명하자. 이름에서부터 알 수 있듯이, 포인터는 '''가리키는 것'''(Point+er)을 의미한다. 다시 말해서, 변수는 변수인데, 화살표처럼 생긴 변수라고 이해하면 된다. 복잡하다면 그냥 변수의 메모리의 주소를 저장하는 상자(주소록)라고 생각해주자.
먼저 '''포인터'''(Pointer)라는 개념부터 설명하자. 이름에서부터 알 수 있듯, 포인터는 '''가리키는 것'''(Point+er)을 의미한다. 다시 말해서, 변수는 변수인데, 화살표처럼 생긴 변수라고 이해하면 된다.


그러면, 우리가 무언가를 가리킬 때 필요한게 무엇인지 잘 생각해보자. 다른 정보는 없어도 그 대상이 위치한 곳이 어딘지를 알아야하지 않을까? 바로 포인터 변수는 자신이 가리키는 대상의 위치, 즉 '''메모리 상의 주소'''를 가지고 있는 변수가 되겠다. 제어판 하드웨어 관리자에 들어가면 0x00000어쩌고 써있는 걸 본적이 있을 것이다. 그게 바로 메모리 주소다. 즉, 포인터 값 그 자체는 내가 가리키는 주소를 의미한다는 것이다.
그러면, 우리가 무언가를 가리킬 때 필요한게 무엇인지 잘 생각해보자. 다른 정보는 없어도 그 대상이 위치한 곳이 어딘지를 알아야하지 않을까? 바로 포인터 변수는 자신이 가리키는 대상의 위치, 즉 '''메모리 상의 주소'''를 가지고 있는 변수가 되겠다. 즉, 포인터 값 그 자체는 내가 가리키는 곳을 의미한다는 것이다.


그렇다면, 포인터 변수를 표기하는 방법을 조금 더 살펴보자. 이 표기법 때문에 많이 헷갈리곤 하는데, 다음 표를 잘 보면서 이해해보자.
그렇다면, 포인터 변수를 표기하는 방법을 조금 더 살펴보자. 이 표기법 때문에 많이 헷갈리곤 하는데, 다음 표를 잘 보면서 이해해보자.
806번째 줄: 793번째 줄:
|}
|}


이 부분이 많이 헷갈릴 것이다. 일단 변수를 선언하는 것 부터가 문제가 될 수 있다.
이 부분이 많이 헷갈릴 것이다. 일단 변수를 선언하는 것부터가 문제가 될 수 있다.


{| class="wikitable"
{| class="wikitable"
839번째 줄: 826번째 줄:
! colspan="4" | 전제 조건
! colspan="4" | 전제 조건
|-
|-
| colspan="4" | <syntaxhighlight lang="c">
| colspan="4" | <source lang="c">
int a = 5;
int a = 5;
int *b;
int *b;
845번째 줄: 832번째 줄:
b = &a;
b = &a;
c = &b;
c = &b;
</syntaxhighlight>
</source>
|-
|-
! 표기법
! 표기법
1,077번째 줄: 1,064번째 줄:
레지스터 eax에 메모리 주소가 들어 있다고 하자.
레지스터 eax에 메모리 주소가 들어 있다고 하자.
그렇다면 이 eax에 있는 메모리 주소 값을 CPU가 타고 들어가 그 메모리 셀의 값을 ecx 레지스터에 복사하고자 한다면 mov ecx, [eax] 를 사용해야한다.
그렇다면 이 eax에 있는 메모리 주소 값을 CPU가 타고 들어가 그 메모리 셀의 값을 ecx 레지스터에 복사하고자 한다면 mov ecx, [eax] 를 사용해야한다.
상위 언어인 C언어로 표현하자면, int ecx = *eax;
상위언어인 C언어로 표현하자면, int ecx = *eax;
mov ecx, [eax]
mov ecx, [eax]
int ecx = *eax;
int ecx = *eax;
1,083번째 줄: 1,070번째 줄:
레지스터 eax에 값이 들어 있다고 하자.
레지스터 eax에 값이 들어 있다고 하자.
그렇다면 이 eax에 있는 값을 ecx 레지스터에 복사하고자 한다면 mov ecx, eax를 사용해야한다.
그렇다면 이 eax에 있는 값을 ecx 레지스터에 복사하고자 한다면 mov ecx, eax를 사용해야한다.
상위 언어인 C언어로 표현하자면, int ecx = eax;
상위언어인 C언어로 표현하자면, int ecx = eax;
mov ecx, eax
mov ecx, eax
int ecx = eax;
int ecx = eax;


만약 메모리 주소를 CPU가 알고 있어서 메모리 셀에 있는 값에 엑세스를 할 때, 해당 메모리 주소를 레지스터에 저장하고 싶으면 lea edx, [eax] 를 사용해야 한다.
만약 메모리 주소를 CPU가 알고 있어서 메모리 셀에 있는 값에 엑세스를 할 때, 해당 메모리 주소를 레지스터에 저장하고 싶으면 lea edx, [eax] 를 사용해야한다.
상위 언어인 C언어로 표현하자면, int *edx = &eax;
상위언어인 C언어로 표현하자면, int *edx = &eax;
lea edx, [eax]
lea edx, [eax]
int *edx = &eax;
int *edx = &eax;
1,103번째 줄: 1,090번째 줄:


=== 구조체 ===
=== 구조체 ===
구조체는 와플틀과 같은 역할을 한다. 구조체는 서로 다른 형식이나 크기의 변수들을 모은 변수 집단. 문자열 배열, 정수, 실수형 변수를 구조체라는 것에 한데 모아 한 묶음으로 만들 수 있다. 배열은 '사람1, 사람2, 사람3, 사람4' 처럼 성격이 같은 변수의 묶음 구조체는 '키, 몸무게, MBTI'같이 성격이 서로 다른 변수의 묶음이다.
구조체는 int처럼 struct 키워드를 앞에 적어준다.
<syntaxhighlight lang = c>
// 이렇게 책을 나타내는 구조체를 만든다.
struct book {
    int id;
    char title[100];
    char author[100];
}
</syntaxhighlight>
이 구조체는 바로 쓸 수는 없고 구조체 변수를 따로 생성해야 한다. 변수 선언 전까지 구조체는 빵틀에 불과하다.
<syntaxhighlight lang = c>
int main(void)
{
    struct book book1; //책 1
    struct book book2; //책 2
}
//이런식으로 책 변수(구조체)를 만들어 줄 수 있다.
</syntaxhighlight>
이렇게 구조체를 만들고 변수까지 만들어줬다. 필요할 때 구조체 변수에 각 하위 변수(멤버)에 값을 넣어주면 된다.
<syntaxhighlight lang = c>
    book1.id = 10;
    strcpy(book1.author, "어니스트 헤밍웨이")
    strcpy(book1.titile, "노인과 바다")
</syntaxhighlight>
이렇게 '.' 마침표를 찍어 book1의 저자, book1의 제목 변수에 접근할 수가 있다. 멤버가 문자열인 경우는 book1.id처럼 바로 대입해 줄 수는 없고 strcpy나, scanf 같은 함수를
이용해서 값을 넣어줘야 한다. 문자열은 그냥 넣을 수 없게 되어 있는데 이 두 함수들은 문자열을 넣을 수 있게 하는 장치가 있는 것 같다.
book1.id같은 구조체의 멤버들은 변수 취급이 가능하다. 값을 불러올 때도 book1.id로 쓰면 된다.
==== 구조체 포인터 ====
==== 포인터를 멤버로 가지는 구조체 ====
=== 공용체 ===
=== 공용체 ===
공용체도 구조체와 비슷한데 같은 메모리 영역을 여러 개의 변수들이 공유할 수 있게 한다.
<syntaxhighlight lang = C>
union abc {
    char a;
    int b;
    float c;
}
</syntaxhighlight>
=== 열거형 ===
=== 열거형 ===
=== typedef ===
'''사용자 정의 자료형'''
<syntaxhighlight lang = C>
typedef unsigned char uchar;
typedef long double ldouble;
</syntaxhighlight>
unsigned char이나 long double은 자료형 이름이 너무 길어서 불편하다면 위와 같이 uchar, ldouble로 줄여 쓸 수 있다.
바로 위에서 배운 구조체나 공용체도 따로 자료형으로 만들어버릴 수 있다.
<syntaxhighlight lang = C>
struct student{
    char name[8];
    int id;
}
typedef struct student STUDENT;
</syntaxhighlight>
이제 struct student a1이 아니라
STUDENT a1로 구조체 변수를 만들어낼 수가 있다.
<syntaxhighlight lang = C>
typedef struct student{
    char name[8];
    int id;
} STUDENT;
</syntaxhighlight>
student 자료형 정의는 위처럼 쓸 수도 있다.


=== 파일 입출력 ===
=== 파일 입출력 ===
<syntaxhighlight lang = C>
<source lang = C>
FILE * 변수이름 = fopen("파일이름", "설정");
FILE * 변수이름 = fopen("파일이름", "설정");


1,184번째 줄: 1,100번째 줄:
FILE * fout = fopen("fout.txt", "w");
FILE * fout = fopen("fout.txt", "w");
FILE * fa = fopen("fa.txt", "a");
FILE * fa = fopen("fa.txt", "a");
</syntaxhighlight>
</source>
'변수이름'에는 사용할 이름을 넣어주고, '파일이름'에는 사용할 파일의 이름을 넣어준다. '설정'에는 파일을 어떻게 사용할 것인지 넣어준다.
'변수이름'에는 사용할 이름을 넣어주고, '파일이름'에는 사용할 파일의 이름을 넣어준다. '설정'에는 파일을 어떻게 사용할 것인지 넣어준다.


1,199번째 줄: 1,115번째 줄:
<nowiki>#</nowiki>define은 특정한 문자(이름)를 찾아 다른 형태(토큰)로 바꾼다. 두 줄 이상으로 작성하고 싶을 때에는 '\' 를 이용하면 된다.
<nowiki>#</nowiki>define은 특정한 문자(이름)를 찾아 다른 형태(토큰)로 바꾼다. 두 줄 이상으로 작성하고 싶을 때에는 '\' 를 이용하면 된다.


<syntaxhighlight lang=c>
<source lang=c>
#define 이름 토큰
#define 이름 토큰
</syntaxhighlight>
</source>


작성
작성
<syntaxhighlight lang=c>
<source lang=c>
#define Int_Max 2147483647
#define Int_Max 2147483647
int max = Int_Max;
int max = Int_Max;
</syntaxhighlight>
</source>


결과
결과
<syntaxhighlight lang=c>
<source lang=c>
int max = 2147483647;
int max = 2147483647;
</syntaxhighlight>
</source>


함수와 비슷한 형태로 작성하면 함수같이 사용할 수도 있다.
함수와 비슷한 형태로 작성하면 함수같이 사용할 수도 있다.


<syntaxhighlight lang=c>
<source lang=c>
#define 이름(인자) 토큰
#define 이름(인자) 토큰
</syntaxhighlight>
</source>


작성
작성
<syntaxhighlight lang=c>
<source lang=c>
#define Sum(X, Y) X + Y
#define Sum(X, Y) X + Y
int sum = Sum(1, 2);
int sum = Sum(1, 2);
</syntaxhighlight>
</source>


X나 Y가 아니라 다른 것을 사용해도 상관없다. 수도 상관없다.
X나 Y가 아니라 다른 것을 사용해도 상관없다. 수도 상관없다.


결과
결과
<syntaxhighlight lang=c>
<source lang=c>
int sum = 1 + 2;
int sum = 1 + 2;
</syntaxhighlight>
</source>


=====#undef=====
=====#undef=====
1,237번째 줄: 1,153번째 줄:


작성
작성
<syntaxhighlight lang=c>
<source lang=c>
#define PI 3.141592
#define PI 3.141592
int pi = PI;
int pi = PI;
#undef PI
#undef PI
int pi = PI;
int pi = PI;
</syntaxhighlight>
</source>


결과
결과
<syntaxhighlight lang=c>
<source lang=c>
int pi = 3.141592;
int pi = 3.141592;
int pi = PI;
int pi = PI;
</syntaxhighlight>
</source>
int pi = PI; 부분에서 오류를 뱉어낸다. #undef로 무효화된 매크로는 그 밑으로 더 이상 작동하지 않는다. 사용 위치에 주의할 필요가 있다.
int pi = PI; 부분에서 오류를 뱉어낸다. #undef로 무효화된 매크로는 그 밑으로 더 이상 작동하지 않는다. 사용 위치에 주의할 필요가 있다.


1,254번째 줄: 1,170번째 줄:
특정 파일의 내용을 가져와서 포함시킨다.
특정 파일의 내용을 가져와서 포함시킨다.


<syntaxhighlight lang = c>
<source lang = c>
#include <stdio.h>
#include <stdio.h>
int main(void)
int main(void)
{
{
    printf("Hello, World!");
printf("Hello, World!");
    return 0;
return 0;
}
}
</syntaxhighlight>
</source>


위 소스 코드에서, #include <stdio.h>의 위치에 stdio.h 헤더파일의 내용이 옮겨진다. printf함수는 stdio.h 헤더파일 내에 선언되어 있는 함수이다.
위 소스 코드에서, #include <stdio.h>의 위치에 stdio.h 헤더파일의 내용이 옮겨진다. printf함수는 stdio.h 헤더파일 내에 선언되어 있는 함수이다.


<syntaxhighlight lang = c>
<source lang = c>
#include <헤더파일>
#include <헤더파일>
#include "헤더파일"
#include "헤더파일"
</syntaxhighlight>
</source>


이렇게 두 가지 모양으로 쓸 수 있는데, <>는 컴파일러에 지정되어 있는 폴더에서 헤더파일을 찾고, ""는 소스 코드 파일이 있는 폴더에서 헤더파일을 찾는다.
이렇게 두 가지 모양으로 쓸 수 있는데, <>는 컴파일러에 지정되어 있는 폴더에서 헤더파일을 찾고, ""는 소스 코드 파일이 있는 폴더에서 헤더파일을 찾는다.
1,274번째 줄: 1,190번째 줄:
조건이 참이냐 거짓이냐에 따라 컴파일 되는 부분을 정할 수 있다. 조건문과 비슷하다. #if는 if, #else는 else, #elif는 else if와 같으며 #endif는 여기까지가 조건부 컴파일이라는 의미이다.
조건이 참이냐 거짓이냐에 따라 컴파일 되는 부분을 정할 수 있다. 조건문과 비슷하다. #if는 if, #else는 else, #elif는 else if와 같으며 #endif는 여기까지가 조건부 컴파일이라는 의미이다.
======#if======
======#if======
<syntaxhighlight lang = c>
<source lang = c>
#if 조건
#if 조건
내용1
내용1
#endif
#endif
내용2
내용2
</syntaxhighlight> 조건은 일반 변수를 적을 수가 없다. 조건의 내용이 참일 경우 #if ~ #endif까지의 내용(내용1)을 컴파일 한다. 하지만 내용1만이 컴파일 되는 것이 아니라 내용2역시 컴파일 된다.
</source>
조건의 내용이 참일 경우 #if ~ #endif까지의 내용(내용1)을 컴파일 한다. 하지만 내용1만이 컴파일 되는 것이 아니라 내용2역시 컴파일 된다.
======#else======
======#else======
<syntaxhighlight lang = c>
<source lang = c>
#if 조건
#if 조건
내용1
내용1
1,287번째 줄: 1,204번째 줄:
내용2
내용2
#endif
#endif
</syntaxhighlight>
</source>
조건이 참이면 내용1을, 거짓이면 내용2를 컴파일 한다.
조건이 참이면 내용1을, 거짓이면 내용2를 컴파일 한다.
======#elif======
======#elif======
<syntaxhighlight lang = c>
<source lang = c>
#if 조건1
#if 조건1
내용1
내용1
1,296번째 줄: 1,213번째 줄:
내용2
내용2
#endif
#endif
</syntaxhighlight>
</source>
조건1이 참이면 내용1을 컴파일 한 다음 #endif를 만나고 끝마친다. 거짓이면 내려간다. #elif를 만나고 조건2가 참이면 내용2을 컴파일 하고, 거짓이면 내려가 #endif를 만나 끝마친다.
조건1이 참이면 내용1을 컴파일 한 다음 #endif를 만나고 끝마친다. 거짓이면 내려간다. #elif를 만나고 조건2가 참이면 내용2을 컴파일 하고, 거짓이면 내려가 #endif를 만나 끝마친다.
======#endif======
======#endif======
조건부 컴파일을 끝마친다.
조건부 컴파일을 끝마친다.
=====#ifdef=====
=====#ifdef=====
<syntaxhighlight lang = c>
<source lang = c>
#ifdef 식별자
#ifdef 식별자
</syntaxhighlight>
</source>
if defined. #if와 쓰임새가 같은데 만약 식별자가 정의된 경우 참, 아닌 경우 거짓이다.
if defined. #if와 쓰임새가 같은데 만약 식별자가 정의된 경우 참, 아닌 경우 거짓이다.
=====#ifndef=====
=====#ifndef=====
<syntaxhighlight lang = c>
<source lang = c>
#ifndef 식별자
#ifndef 식별자
</syntaxhighlight>
</source>
if not defined. #ifdef의 반대이다. 식별자가 정의된 경우 거짓, 아닌 경우 참이다.
if not defined. #ifdef의 반대이다. 식별자가 정의된 경우 거짓, 아닌 경우 참이다.
=====#error=====
=====#error=====
1,315번째 줄: 1,232번째 줄:
컴파일러에게 명령을 전달한다.
컴파일러에게 명령을 전달한다.


<syntaxhighlight lang=c>
<source lang=c>
#pragma 명령
#pragma 명령
</syntaxhighlight>
</source>


컴파일러마다 다르니 자세한 것은 [[추가바람]]
컴파일러마다 다르니 자세한 것은 [[추가바람]]
 
{{쉽게 배우는 프로그래밍 입문}}
[[분류:프로그래밍 시리즈|C]]
[[분류:프로그래밍 시리즈|C]]
{{각주}}
{{각주}}
리브레 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포됩니다(자세한 내용에 대해서는 리브레 위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요.
글이 직접 작성되었거나 호환되는 라이선스인지 확인해주세요. 리그베다 위키, 나무위키, 오리위키, 구스위키, 디시위키 및 CCL 미적용 사이트 등에서 글을 가져오실 때는 본인이 문서의 유일한 기여자여야 하고, 만약 본인이 문서의 유일한 기여자라는 증거가 없다면 그 문서는 불시에 삭제될 수 있습니다.
취소 편집 도움말 (새 창에서 열림)

| () [] [[]] {{}} {{{}}} · <!-- --> · [[분류:]] · [[파일:]] · [[미디어:]] · #넘겨주기 [[]] · {{ㅊ|}} · <onlyinclude></onlyinclude> · <includeonly></includeonly> · <noinclude></noinclude> · <br /> · <ref></ref> · {{각주}} · {|class="wikitable" · |- · rowspan=""| · colspan=""| · |}

이 문서는 다음의 숨은 분류 1개에 속해 있습니다: