IT Japan

제 1장 - C의 구조와 변수 본문

IT/Programming

제 1장 - C의 구조와 변수

swhwang 2016. 3. 22. 00:06
반응형

* 제 1장 - C의 구조와 변수 




요즈음은 윈도우즈의 시대라고들 한다. 

하지만 그 Windows에서 돌아가는 프로그램을 작성하려고 해도 C언어가 기 

반이 되어야 한다. 그래야 훨씬 수월하다. Windows프로그래밍 공부의 시작 

요령은 마지막 회에서 언급하고자 한다. 


물론, 일반인들은 언어를 배울 필요가 없다. 하기야 이 글을 읽는 여러분 

들 중의 대부분은 컴퓨터에 대한 지적호기심을 가지고 있는 사람들과 전산 

관련분야로 진출하려는 사람들일 것이다. 모처럼 결심을 하고 컴퓨터 언어 

라는 전혀 새로운 언어 세계에 도전을 결심하고 남들이 모두들 배우라는 

C언어라는 걸물을 만나게 되었을 것이다. 


그렇다! C언어는 분명 최고의 언어이다. 프로그램 개발에 최적을 효율성 

을 제공하고, C++,Assembly등 다른 언어로의 전환도 편리하며, 앞으로 표 

준이 될 윈도우즈 응용 프로그램도 C를 모르고서야 도무지 작성하기가 난 

감하다는 것이다. 


바로 여러분들은 최상의 선택을 하였으나, 앞을 가로막고 있는 난관이 보 

통이 아닐 것이다. 

C언어는 여타 언어에 비해 많은 장점과 다양한 기능을 가지고 있어 대부 

분의 프로그램들이 바로 이 C언어에 의해 코딩되고 있다. 


요즘의 주요 C 컴파일러들의 대표적인 특징으로는 


가. 수행속도가 빠르며 사용이 편리한 통합환경에 의하여 최적 프로그램 

개발환경을 구축할 수가 있다. 

나. 명령행 처리도 가능하여, 빠르고 간편한 개발이 가능하다. 

다. ANSI 표준에 근거하고 있으며, 방대한 양의 자체 함수를 가지고 있다. 

라. 6종류의 메모리 모델을 지원함으로서 큰 규모의 프로그램도 작성이 가 

능하다. 

마. 어셈블리와 혼용하여 쓸 수 있으며, 다른 고급언어와의 연결(Link)도 

가능하다. 


등등 다른 컴퓨터 언어에 비하여 많은 장점들을 가지고 있어 많은 사람들 

이 C언어로 프로그래밍을 하고 있고, 또 많이들 배우고 있다. 이러한 특 

성들이 전문 프로그래머에게는 다양한 표현방식을 제공하여 편리하겠지만 

초보자의 경우에는 반대로 모든 특성을 이해하는데 많은 혼란을 가져올 수 

있는 요소가 된다. 그렇기 때문에 C가 배우기 어려운 언어라는 말이 나오 

기 마련이다. 아울러 포기하는 사람도 많다. 


이 강좌의 목적은 이제 C를 배울려는 사람들과 과거에 C를 공부하다가 중 

도에 포기한 경험이 있는 이들로 하여금 자연스럽게 C의 세계로 입문할 수 

있도록 하기 위한 것이다. 이 강좌를 읽다보면 모르는 사이에 저절로 C로 

의 입문이 가능해 지리라 믿는다. 

이 글의 예제들은 모든 컴파일러가 지원을 하는 표준 C이므로 컴파일러가 

무엇인지는 상관을 하지 않아도 된다. 




1. C의 구조 


C에서는 프로그램의 형식이 있어 여기에 맞게 기술해야 한다. 형식이라고 

해서 그리 대단한 것은 아니다. 여기 예제 프로그램이 있다. 


/* -- Sample -- */ 

main() 

printf("Hello, World!\n"); 


함수가 무엇인지는 여러분들 모두가 잘 알고 있을 것이다. 컴언어에서 함 

수란 어떠한 일을 처리하는 작은 프로그램이라고 보면 된다. 


C프로그램은 기본적으로 함수들의 집합으로 구성되어 있다. 그러므로 위 

의 프로그램은 main이라는 이름의 함수와 printf라는 이름의 함수로 구성 

되어 있음을 알 수가 있다. main()함수는 다른 자질구레한 기능을 하는 함 

수(여기서는 printf()함수)들을 모두 포함을 하는 가장 기본적인 함수이므 

로 프로그램에 반드시 포함이 되어야 하며, 프로그램의 내용은 { } 기호로 

묶어서 시작과 끝을 나타낸다. 


C에서는 영어의 대문자와 소문자를 구별하므로 위의 예제를 반드시 소문 

자로 입력하여야 한다(abc와 ABC가 서로 다르게 인식된다). C에서는 변수 

명을 제외한 프로그램의 대부분의 명령어를 소문자로 기술한다. 

C에서는 주석문을 /*과 */로 묶어서 표현한다. 주석문은 프로그램의 실행 

과는 무관하며, 적절히 붙여두면 후에 그 프로그램을 이해하는데 도움이 

될 것이다. 


보통 프로그램의 본체는 관례적으로 { 다음에 서너칸 쯤 우측으로 물러나 

서 기술한다. 이러한 것을 indent(단짓기)라고 한다. 


베이직의 PRINT문과 유사한 기능을 하는 것이 출력의 기능을 담당하는 pr 

intf()함수이다. 화면에 출력하고 싶은 문자는 printf()함수의 괄호안에 " 

로 묶어서 나타낸다. C에서는 문장의 맨끝에 반드시 ; 을 붙여야 한다는 

점을 명심해야 한다. 또한 main() 다음에는 ; 를 붙이지 않는다는 것도 명 

심하기 바란다. \n(개행문자라고 한다)은 행을 바꾸라는 의미이다. 


printf("Hello, World! \n"); 

--------------## -> 출력후 줄을 바꿈(개행문자) 

화면에 그대로 출력. 


우선 예제를 통해 알 수 있는 C 프로그램의 기초적인 사항은, 


1) C에는 행번호가 없다. 

2) 대문자와 소문자가 구별되며, 주로 소문자에 기초하여 작성된다. 

3) C는 main()으로 시작한다. 

4) 프로그램(함수)의 본체는 { 와 }로 묶는다. 

5) 한 문장은 반드시 ; 로 끝난다.(초보자가 실수를 잘한다) 

6) 주석문은 /* */로 묶어 표시한다. 




2. C의 변수 


일반적으로 상수란 어떠한 정해진 값을 말하고, 변수란 어떠한 값을 보존 

하는 상자에 비유할 수가 있는데, 그 상자를 구분하기 위해서 붙이는 이름 

이 변수명이다. 


C에서 변수명이 갖추어야 할 요건은 다음과 같다. 


1)변수명은 보통 8문자까지 인식한다. 

2)변수명의 첫문자는 영문자(A-Z,a-z:대소문자가 엄격히 구분된다)나 _ 

로 시작하며, 그 이후의 문자는 영문자나 숫자, 밑줄 어느 것이라도 상 

관없다(밑줄로 시작하는 변수는 주로 시스템 프로그램에서 사용하므로 

실제의 경우에는 피하는 것이 관례이다). 3ds : X , Son <> son 

3)명령어나 기존의 함수명은 변수명으로 사용할 수는 없으나 포함할 수는 

있다. for : X fortune : O 

4)프로그램에서 사용할 변수는 반드시 프로그램의 첫머리에서 그 형:Type 

을 정의해야 한다. int a, float b, char c ... 


위의 사항 중 초보자들이 가장 번거롭게 생각하는 것이 바로 4번이다. 

습관이 되면 불편하지 않게 되며, 오히려 프로그램의 분석에 커다란 도움 

을 주는 요소이며 구조적 사고를 하는데 도움을 주는 요소임을 깨달아야 

한다. 



그러면 다음의 예제를 통해 변수의 형을 정의하는 방법을 익혀 보자. 


<예제1> 밑변이 21, 높이가 4인 삼각형의 넓이를 구하는 프로그램 작성. 

1: main() 

2: { 

3: int a,b; 

4: float c; 

5: a=21; 

6: b=4; 

7: c=a*b/2.0; 

8: printf("넓이=%f\n", c); 

9: } 


3행과 4행에서 변수 a와 b를 정수형으로, c는 실수형으로 선언한 것을 볼 

수 있다. int는 그 다음의 변수를 정수형으로, float는 실수형으로 선언해 

주는 예약어이다.여기서 변수 c를 실수형으로 선언한 이유는 다음과 같다. 

위 프로그램의 결과는 나눗셈(/)이 있으므로 소수부분이 발생하는데,정수 

형의 변수에 소숫점을 포함하는 실수형의 자료를 기억시키면 소수 부분이 

절삭된다. 그러므로 계산의 결과를 고려하여 적절한 형(Type)을 선언하여 

야 한다. 


--------------------------------------------------------------------------------


Transfer interrupted!


값을 부여할 수가 있다. 3 - 7행을 좀 

더 간단히 하면 다음과 같다. 


int a=21, b=4; 

float c; 

c=a*b/2.0; 


C에서는 연산결과가 변수나 상수의 형에 의해 달라지게 된다. 


정수 (연산) 정수=정수 

정수 (연산) 실수=실수 

실수 (연산) 실수=실수 


그렇다면 3/4*4의 연산 결과는 얼마겠는가? 


3이라고 생각하겠지만 정답은 0이다. 3/4가 정수와 정수의 연산이므로 

소수점 이하가 절삭되어 0이 된다. 이 0에다 4를 곱했으니 결과가 0이 되 

는 것이다. 


그러면 3/4.0*4의 결과는 얼마이겠는가? 대다수는 3이라고 생각하겠지만 

여기서는 3이 아니라 3.0이 된다. 3/4.0이 정수와 실수의 연산이므로 연산 

결과는 실수로 보존되어 0.75가 된다. 다음의 0.75 * 4 역시 실수와 정수 

의 연산이므로 결과는 실수가 되어 3.0이 된다. 3은 정수이고 3.0은 실수 

이므로 3은 올바른 답이 아니다. C에서는 3과 3.0을 엄격하게 구분하고 있 

으므로 혼돈하는 실수를 범하지 말기를 바란다. 이러한 실수는 프로그램의 

실행결과에 심각한 영향을 미칠수 있기 때문에 항상 주의해야 한다. 


8행에서 " 안의 문자열을 제어 문자열이라고 하며, 제어 문자열은 인쇄가 

능 문자열과 기능 문자열로 구분된다. 인쇄가능 문자열은 화면에 그대로 

출력되며, 기능 문자는 화면에 출력되는 대신에 특수한 처리를 한다. 이를 

테면 printf()함수 안의 \n 따위가 기능문자에 속한다. 


|------| <-- 서로 짝이 된다 

printf("넓이=%f \n",c); 

=======++=** # 

== : 화면에 그대로 출력된다(인쇄가능 문자) 

++ : 인수(변수)를 10진 실수로 출력한다(형변환기호:기능문자) 

** : 출력후에 줄을 바꾼다(기능문자) 

, : 제어문자열과 인수(변수)와의 구분 

# : 변수 


위의 도해에서 보듯이 %f는 제어문자열 다음의 인수와 한 쌍을 이룬다. 

그러므로 인수가 3?BR> 이면 변환 기호도 3개가 기술되어야 한다. 정수형 인 

수를 출력할 경우에는 %f대신 %d를 기술한다. 


printf()는 인수를 제어 문자열의 형식(format)대로 변환하여 출력해 주 

는 함수이다. 그러면 다른 예제를 통해 형변환 기호의 기능을 좀더 살펴보 

자. 


<예제2> 10 * 50=500 

100 / 3.0=33.3 을 출력하는 프로그램 작성. 


1: main() 

2: { 

3: int a=10,b=50,c=100; 

4: float d=3.0; 

5: int sum1; float sum2; <- 두 문장이 한줄에 들어가도 된다 

6: sum1=a * b; (;로 구분되어 있음에 유의) 

7: sum2=c / d; 

8: printf("%3d * %3d=%4d\n",a,b,sum1); 

9: printf("%3d / %3.1f=%4.1f\n",c,d,sum2); 

10: } 


9행의 의미를 분석하면, 


* # @ * # @ -->기능문자와 인수의 순서 

printf("%3d / %3.1f=%4.1f\n",c,d,sum2); 가 일치한다. 

###===@@@@@===$$$$$ -------- 


### : 정수를 세자리 넓이로 출력 

@@@ : 실수를 총 세자리 넓이로, 소수점이하 한 자리로 출력 

$$$ : 실수를 네자리 넓이로, 소수이하를 한자리로 출력 

=== : 화면에 그대로 출력(공백포함) 

--- : 인수( , 로 분리) 


위의 예에서 인수 a에 대한 %3d는 3자리를 확보한 후에 우측을 기준으로 

출력하라는 의미로서 좌측의 남는 한칸은 공백으로 채워진다. ( ' 10' ) 


좌측을 기준으로 출력할 경우는 %-3d와 같이 수치앞에 -기호를 붙인다. 

자리수를 실수로 지정해서 출력할 경우에는 %7.3f처럼 기술한다. 7은 전체 

자리수이며, 3은 소수 이하 자리수이다. 만약 소수 이하가 3자리를 초과할 

경우에는 반올림이 되어 출력된다. 이 경우에도 우측을 기준으로 출력되며 

좌측을 기준으로 출력할 경우에는 %-7.3f처럼 기술하면 된다. 만약 인수 

(변수)의 값이 변환기호의 자리수를 초과할 경우에는 변환 기호는 무시되 

어 인수의 자리수 길이만큼 출력된다. %7.3f로 3.14159를 출력하면 다음과 

같다. 


'^^3.142' (^은 공백을 나타냄) -->소수 네째자리에서 반올림된다 



printf()함수의 인수란에서 수식을 쓸 수도 있다. 즉, 8행을 printf("%3d 

* %3d=%4d\n",a,b,a*b);와 같이 기술해도 된다. 이 때는 sum1을 선언하 

지 않아도 된다(당연한 얘기!) 


이번장에서는 형변환 기호중 %d와 %f에 대해 알아 보았다. 하지만 다른 

것도 있는데 변수의 형에 대해 좀더 깊이 공부하는 2장에서 언급하겠다. 


수학에서는 소숫점을 포함하지 않는 모든 수가 정수이지만, 컴퓨터에서 

는 정수의 범위가 정해져 있다. 

16비트(1워드)를 기본 단위로 하는 컴퓨터(일반PC)에서 -32,768 -- 32,7 

67사이중 소수점을 포함하지 않는 수치만을 정수로 취급한다. 32비트를 1 

워드로 하는 중형급 이상의 컴에서는 정수의 범위가 -2,147,483,648 -- 2, 

147,483,647사이의 수치로 확장된다. 


컴퓨터에서 변수형에 따라 범위가 제한되어 있는 이유와 원리는 다음 장 

에서 알아보기로 하자. 




3. 문자형 변수 


C에서는 프로그램의 선두에서 변수의 형을 정의하는데에 따라 ab가 수치 

변수가 되기도 하고 문자변수가 되기도 한다. 문자변수 중에서도 단일 문 

자를 기억하는 변수와 문자열을 기억하는 변수의 선언방식이 조금 다르다. 


<예제3> '우리는 지금 C를 배우고 있어요.'을 출력하는 프로그램을 문자 

변수를 이용하여 작성하라. 변수 s에 '우리는 지금'을, 변수 c에 

'C'를 기억시키고, '를 배우고 있어요.'는 문자열 상수로서 출 

력하라. 


1: main() 

2: { 

3: char c, *s; 

4: s="우리는 지금"; /* 문자열은 "로 둘러싸고, */ 

5: c='C'; /* 단일문자는 '로 둘러싼다 */ 

6: printf("%s %c %s\n",s,c,"를 배우고 있어요."); 

7: } 


위에서 편의상 한글을 사용하였는데 한글의 한 문자는 영문의 두 문자에 

해당한다. 그러므로 5행을 c='씨'라고 표현해서는 안된다. 


3행의 char은 다음의 변수가 문자형 변수임을 선언하는 예약어이다. 문자 

형변수는 단 1개의 문자만을 기억하는 것을 의미한다. 만약 문자열을 기억/ 

시키고 싶으면 변수명 앞에 *를 붙여서 *s처럼 선언하면 된다. *는 포인터 

를 의미하는데, 우선은 문자열 변수는 변수명 앞에 *를 붙여서 선언한다 

라고 알고 있자. * 는 선언할 때에만 쓰이고, 값을 대입하거나 출력하는 

경우에는 쓰지 않는다(쓰면 안된다는 것은 아니고, 우선은 쓰지 않는 것 

으로 하자:6장에서 배울 것이다). 


4행은 문자열을 대입하는 보기이며, 5행은 문자를 대입하는 예이다. 그리 

고6행에서 문자열 자체나 수식자체도 인수가 될 수 있다. 

C에서는 변수의 형 선언과 함께 초기값을 부여할 수도 있다고 하였으므 

로, 3 -- 5행을 한 문장으로 표현하면 다음과 같다. 


char c='C', *s= "우리는 지금"; 


물론 위의 프로그램을 printf("우리는 지금 C를 배우고 있어요.\n");처럼 

1행으로도 처리가 가능하다. 




4. 포맷 코드(형변환 기호) 


포맷 코드, 즉 출력 양식을 의미한다. C에서는 다양한 출력 양식을 제공 

한다. 밑의 표에서 code앞에 printf를 붙여 반드시 실행해 보기를 바란다. 


<표1> 포맷 코드 a=1234, b=3.14159, c='A', s="ABCD" (=:공백) 

+-------------+--------+------------------------------------+ 

| code |출력형태| 설 명 | 

+-------------+--------+------------------------------------+ 

|("%d",a) |1234 | 정수의 출력 | 

|("%8d",a) |====1234| 수치를 우측을 기준으로 8자리 출력| 

|("%-8d",a) |1234====| 좌측을 기준으로 8자리 출력 | 

|("%+8d",a) |===+1234| 수치앞에 부호 | 

|("%08d",a) |00001234| 수치앞의 공백을 0으로 채움 | 

|("%+08d",a) |+0001234| 부호붙이고 공백을 0으로 채움 | 

|("%f",b) |3.14159 | 실수의 출력 | 

|("%8.3f",b) |===3.142| 전체 8자리, 소수 3자리 출력 | 

|("%-8.3f",b) |3.142===| 좌측기준 (소수이하 반올림) | 

|("%+8.3f",b) |==+3.142| 부호를 붙여서 출력 | 

|("%08.3f",b) |0003.142| 앞의 공백을 0으로 채움 | 

|("%+08.3f",b)|+003.142| 부호를 붙이고 공백을 0으로 채움 | 

|("%c",c) |A | 문자 출력 | 

|("%8c",c) |=======A| 우측을 기준으로 | 

|("%-8c",c) |A=======| 좌측을 기준으로 | 

|("%s",s) |ABCD | 문자열의 출력 | 

|("%8s",s) |====ABCD| 우측을 기준으로 | 

|("%-8s",s) |ABCD====| 좌측을 기준으로 | 

+-------------+--------+------------------------------------+ 

# 출력하려는 수치, 문자의 길이가 포맷코드보다 크면 포맷코드는 무 

시됨 




5.Escape Sequence(Esc문자열) 


이 문장은 어째 이상하지 않은가? 


printf("멀티미디어 - 덩달이 왈 "아니 얘가 뭘 디민디어?"\n"); 


그러면 "는 어떻게 표현을 할까? 문장내의 "를 표현할때는 "앞에 \를 삽 

입하면 된다. printf("He said, \"I love you.\"\n");와 같이. 


위에서 보는 것과 같이 \ 로 시작하는 문자의 나열을 ESC 문자열이라고 

한다. 이 것은 \" 처럼 \ 다음 문자가 화면에 그대로 출력되는 경우가 있 

고, \n 처럼 화면에 출력되는 대신에 줄을 바꾸는 역할도 있다. 


<표2> 이스케이프 시퀀스 

+------+-----------------+--------------------------------+-------+ 

| e.s | 명 칭 | 기 능 |ASC코드| 

+------+-----------------+--------------------------------+-------+ 

| \a | Beep | '삑'소리를 낸다 | 0x07 | 

| \n | Line feed | 줄을 바꾼다 | 0x0a | 

| \t | TAB | 다음 TAB위치로 이동 | 0x09 | 

| \b | Back Space | 인쇄반대방향으로 1칸 후진 | 0x08 | 

| \r | Carrige Return | Return(Enter) 역할 | 0x0d | 

| \f | Form feed | 출력용지를 1페이지 전진 | 0x0c | 

| \\ | Backslash | \ 출력 | | 

| \' | Apostrophe | ' 출력 | | 

| \" | Quote | " 출력 | | 

| \0 | Null | 아무런 동작도 하지않음 | 0x00 | 

| %% | Percent | % 출력 | | 

+------+-----------------+--------------------------------+-------+ 

# 0x는 16진수를 기술할 때 앞에 붙여주는 기호이다. 

# 또한 \뒤에 직접 8진수인 3자리 수치를 입력함으로써 아스키문자 

를 출력할 수 있다. ( \x00a 는 \n과 같다 ) 



<예제4> 다음 프로그램의 실행결과를 적어보시오. 


1: main() 

2: { 

3: int a=66; 

4: float b=3.14159; 

5: char c=65, *s="알파벳의 첫문자는 "; 

6: printf("%6d\t%-6d\n",a,a); 

7: printf("%6c\t%-6c\n",a,a); 

8: printf("%8.5f\t%-8.5f\n",b,b); 

9: printf("%4c\t%-4c\n",c,c); 

10: printf("%4d\t%-4d\n",c,c); 

11: printf("\n%s%2c",s,c); 

12: printf(". %s\n","끝이라우."); 

13: } 



위의 프로그램에 이상한 부분을 발견하였는가? 


char c=65가 바로 그것인데, 문자 변수에 단일 문자를 기억시킬 때는 

'로 묶는다고 하였는데 이 문장에서는 문자 변수에 수치상수를 대입하였으 

니 오타가 아니냐는 오인도 했을 것이다. 

c를 정수형으로 선언하였다면 65가 대입이 된다. 하지만 지금은 문자형으 

로 선언하였으므로 아스키 코드의 65번 문자 A를 대입하라는 의미가 된다. 

문자 변수에 수치상수를 대입하면 C에서는 그 수치에 해당하는 아스키 값 

을 문자변수에 대입하게 된다( 물론, 이때 수치의 범위는 0 -- 255 사이의 

정수값이라야 한다). 


컴퓨터는 문자를 아스키 코드로 기억하고 저장하므로 이 코드를 수치로 

보느냐, 문자로 보느냐는 출력하기에 달려있다. 다시 말하면, 자료의 변환 

이 자유롭다는 것이다. 그러므로 정수를 %c로 출력하면 그 값을 아스키 코 

드로 하는 문자가 출력되며, 문자를 %d로 출력하면 그 문자의 아스키 코드 

가 출력되게 된다. 


예제의 실행결과는 직접 실행시켜 보기 바란다. 


시작이 반이다. 이제 여러분들은 1회를 무사히 마쳤으니 이 패기로 C의 

초보딱지를 떼게 되는 8장까지 힘차게 따라와 주길 바란다.  


반응형

'IT > Programming' 카테고리의 다른 글

제 6장 - 배열과 포인터  (0) 2016.03.22
제 5장 - 함수 / 기억부류  (0) 2016.03.22
제 4장 - 연 산 자  (0) 2016.03.22
프로그래밍 기초 3  (0) 2016.03.22
제 2장 - C의 입출력 함수 및 수의 표현  (0) 2016.03.22
Comments