Chapter 6
1. Do While
- 탈출 조건 루프
- 루프의 매 사이클 뒤에서 조건을 검사
/* 탈출 조건 루프 */
#include <stdio.h>
int main(void)
{
const int secret_code = 13;
int code_entered;
do
{
printf("13일의 금요일 공포증 치료 동호회에 들어오려면,\n");
printf("비밀 코드 번호를 입력하세요.: ");
scanf("%d", &code_entered);
} while (code_entered != secret_code);
printf("축하합니다! 치료되었습니다!\n");
return 0;
}
- 사용자가 13을 입력할 때까지 입력값들을 읽는다.
do
{
statement(문장);
}
while (expression(표현식) ) ;
- do while 루프 자체가 하나의 문장으로 간주되므로 끝에 세미콜론(;)이 필요하다.
- 루프의 몸체가 실행된 이후에 검사가 이루어지기 때문에 언제나 적어도 한번은 실행된다.
** for문 , while문 / do while 의 차이점
- for루프나 while 루프는 몸체가 실행되기 전에 검사(조건)가 이루어지기 때문에 조건이 맞지않는다면 한번도 실행되지 않는다.
하지만 do while은 최소 한번은 실행되어진다.
- do while문은 패스워드 요구 프로그램 같이 최소한 한번은 실행해야하는 경우에 사용된다.
ex.)
do
{
패스워드를 입력할 것을 요구한다.
사용자의 입력을 읽는다.
} while (입력이 패스워드와 같지 않은 동안);
잘못된 ex.)
do
{
계속할 것인지 사용자에게 묻는다.
어떤 동작을 실행한다.
} while (대답이 '예' 인 동안);
여기서, 사용자가 '아니오'라고 입력한 후에도, 검사가 너무 늦게 이루어지기 때문에, 어떤 동작을 실행한다는 것이 문제가 된다.
** for문이냐? while문이냐?
- 루프가 초기화와 변수 갱신을 가질때 (for문)
- 그밖의 경우 (while문) ex.) while (scanf("%ld",&num)==1) // 입력 받는값을 바로 비교할때
- for루프는 인덱스를 이용하여 카운트하는 루프에 자연스럽다. ex.) for( count = 1 ; count <= 100; count++)
2. 중첩 루프
- 내부에 다른 루프가 들어 있는 루프이다.
- 중첩 루프의 주 용도는 데이터를 행과 열로 표시하는것이다.
/* 중첩 루프 사용문*/
#include <stdio.h>
#define ROWS 6
#define CHARS 10
int main(void)
{
int row;
char ch;
for (row = 0; row < ROWS; row++) /* 라인 10 : 0부터 5까지 루프를 돈다.*/
{
for (ch = 'A'; ch < ('A' + CHARS); ch++) /* 라인 12 : A(ASCII에서 65); 65 < ( 65 + 10); ch++*/
printf("%c", ch); /* A에서 J까지 같은 라인에 출력한다.*/
printf("\n");
}
return 0;
}
- 라인 10에서 시작하는 for 루프를 외부 루프(Outer loop)라 하고, 라인 12에서 시작하는 루프를 내부루프(Inner loop)라한다.
/* 중첩 루프 사용문*/
#include <stdio.h>
#define ROWS 6
#define CHARS 10
int main(void)
{
int row;
char ch;
for (row = 0; row < ROWS; row++) /* 라인 10 */
{
for (ch = 'A'; ch < ('A' + CHARS); ch++) /* 라인 12 */
{
printf("\t%3d",ch);
printf("%c", ch);
//printf("%d\t%c", ch, ch);
}
printf("\n");
}
return 0;
}
- for문 안에 {} (중괄호) 넣자!!!!!!
- for문 초기값은 for루프가 처음 시작할 때 한번만 이루어진다.
3. 변형 중첩 루프
- 외부 루프의 각 사이클마다 내부 루프가 다르게 행동하도록 만들 수 있다.
// 변형 중첩 루프
#include <stdio.h>
int main(void)
{
const int ROWS = 6;
const int CHARS = 6;
int row;
char ch;
for (row = 0; row < ROWS; row++)
{
for (ch = ('A' + row); ch < ('A' + CHARS); ch++)
{
printf("%c", ch);
}
printf("\n");
}
return 0;
}
// 변형 중첩 루프
#include <stdio.h>
int main(void)
{
const int ROWS = 6;
const int CHARS = 6;
int row;
char ch;
for (row = 0; row < ROWS; row++)
{
printf("외부:%1d",row);
for (ch = ('A' + row); ch < ('A' + CHARS); ch++)
{
printf("\t내부:%1d",row);
printf("%c", ch);
}
printf("\n");
}
return 0;
}
4. 배열에 대한 소개
- 배열(array)은 (10개의 char형 값 또는 15개의 int형 값과 같이) 동일한 데이터형을 가진 여러 값들이 연속적으로 저장되어 있는
것이다.
- 배열 전체가 하나의 이름으로 불린다.
- 개개의 항목들, 즉 원소(Element)는 정수 인덱스(Index)를 사용해서 접근할 수 있다.
- float debts[20]; : debts가 20개의 원소를 가진 배열이며, 각각의 원소에는 float형 값을 저장할 수 있다고 선언한다.
debts[0]이 첫번째원소이다.
- debts[5] = 33.54; "debts[5]에 33.54를 대입한다."
- scanf("%f", &debts[4]); "입력값을 float형으로 debts[4]에 넣는다."
*** 함정 카드!!!!
- C는 실행속도를 높이기 위해, 사용자가 인덱스를 바르게 사용했는지 검사하지 않는다.
ex.)
debts[20] = 88.32; // 배열 원소가 없다. 즉, float debts[20]; -> 인덱스 0부터 19까지 잡는다. [20]은 넘어간다.
debts[33] = 828.12; // 배열 원소가 없다.
- 배열에는 어떠한 데이터형도 사용할 수 있다.
int nannies[22]; // 22개의 정수를 저장하는 배열 (인덱스는 0부터 21까지)
char actors[26]; // 26개의 문자를 저장하는 배열 (인덱스는 0부터 25까지)
long big[500]; // 500개의 long형 정수를 저장하는 배열 (인덱스는 0부터 499까지)
** char형 배열의 내용은, 그 배열이 널 문자(\0)를 포함한다면 문자열이 된다.
- 배열의 원소들을 나타내기 위해 사용되는 수들을 첨자(Subscript) 또는 인덱스(Index) 또는 오프셋(Offset)이라고 부른다.
- 인덱스는 반드시 정수 !!!!
- 배열의 원소들은 메모리에 연속적으로 저장된다.
** int당 2바이트 : 방 하나에 16비트(65,536) 들어올 수 있음
** char당 1바이트 : 방 하나에 8비트(256) 들어올 수 있음
*** 배열에 for 루프 사용하기
- 합, 평균, 핸디캡을 출력한다.
* 핸디캡 : 평균과 표준스코어와의 차(-)를 출력한다.
// 배열에 for문 사용하기
#include <stdio.h>
#define SIZE 10 //배열의 크기를 나타내는 명단 상수(SIZE)를 만들기 위해 #define 지시자를 사용한다.
#define PAR 72
int main(void)
{
int index, score[SIZE];
int sum = 0;
float average;
printf("%d개의 골프 스코어를 입력하세요:\n", SIZE);
for (index = 0; index < SIZE; index++)
scanf("%d", &score[index]); // 10개의 골프 스코어를 읽는다.
printf("읽은 스코어들은 다음과 같다:\n");
for (index = 0; index < SIZE; index++)
printf("%5d", score[index]); // 입력을 검증한다.
printf("\n");
for (index = 0; index < SIZE; index++)
sum += score[index]; // 모두 더한다.
average = (float) sum / SIZE; // 평균을 구한다.
printf("스코어의 합= %d, 평균 = %.2f\n", sum, average);
printf("핸디캡이 %.0f.\n 이다.", average - PAR);
return 0;
}
- 사용자가 11개의 수를 타이핑 했지만, 읽기 루프가 10개의 값만 읽기 때문에, 프로그램이 정확하게 10개의 수만 읽었다.
- scanf()는 화이트스페이스를 건너뛰기 때문에, 10개의 수를 한 라인에 모두 입력할 수도 있고, 각각의 수를 한 라인씩 입력하거나,
개행(\n)과 스페이스를 혼합하여 여러 라인에 걸쳐 입력할 수도 있다.
( 입력은 버퍼(임시기억장치)를 거치기 때문에, 타이핑된 수들은 사용자가 엔터키를 눌렀을 때에만 프로그램으로 보내진다.)
- int형 배열의 원소는 int형 변수처럼 취급된다.
- 입력을 읽어 int형 변수 fue에 넣으려면, scanf("%d",&fue)를 사용한다.
- int형 원소 score[index]에 넣으므로 scanf("%d", &score[index])를 사용한다.
- 프로그램에서 반복문을 에코(echo)하는것은 좋은 습관이다.
* 에코(echo) : 문자열을 컴퓨터 터미널에 출력하는 명령어이다. (즉, 맞게 출력되는지 확인하라는 뜻임)
5. 함수의 리턴값을 사용하는 루프
*** pow() : #include <math.h>를 쓰면 pow() 함수를 제공한다!!!!
- 멱승 : 거듭제곱을 뜻한다.
- 리턴값은 다른 변수에 대입될 수도 있다.
- power() 함수를 만들어 for루프를 돌려 실행 해보았다.
#include <stdio.h>
double power(double n, int p) // double형을 리턴한다.
{
double pow = 1;
int i;
for(i = 1; i <= p; i++)
{
//pow = pow * n;
pow *= n;
printf("\ni = %d\t",i);
printf("\np(범위) = %d",p);
printf("\nn = %.2f",n);
printf("\npow = %.1f",pow);
}
return pow; //pow의 값을 리턴한다.
}
int main()
{
printf("%.1f\n\m", power(6.28,3));
}
- 함수를 정의할 때 리턴값의 데이터형을 기술한다.
- 리턴될 값을 지정하기 위해 키워드 return을 사용한다.
- 함수의 데이터형을 선언하려면, 변수를 선언할 때와 같은 방식으로, 함수 이름앞에 데이터형을 붙인다.
- 키워드 return은 뒤에 오는 값을 호출한 함수에 리터하도록 만든다.
- 변수pow의 값을 리턴한다. (그러나 표현식의 값도 리턴 가능) ex.) return 2 * x + b;\
**n은 고정값으로 곱해진다.
[함수와 while문을 써서 사용자 입력받은 수의 거듭제곱을 구하는예제 ]
// 입력받은 수의 정수 거듭제곱을 구한다.
#include <stdio.h>
// 함수 전방선언(Forward declaration): 컴파일러에게 미리 어떤 데이터형이 오게 될지 미리알려주는것
double power(double n, int p); // ANSI 프로토타입
int main(void)
{
double x, xpow;
int exp;
printf("어떤 수와, 원하는 양의 정수 거듭제곱수를");
printf(" 입력하세요.\n끝내려면 q를");
printf(" 입력하세요.\n");
while (scanf("%lf%d", &x, &exp) == 2)
{
xpow = power(x,exp); // 함수 호출
printf("%.3f 의 %d 제곱은 %.5f입니다.\n", x, exp, xpow);
printf("두 수를 입력하세요. 끝내려면 q를 입력하세요.\n");
}
printf("거듭제곱 구하기가 힘들었죠? -- 다신안봐 ^^!\n");
return 0;
}
double power(double n, int p) // 함수 정의를 main()함수 위에 한다면 전방선언 생략가능
{
double pow = 1;
int i;
for (i = 1; i <= p; i++)
pow *= n;
return pow; // pow의 값을 리턴한다.
}
- while (scanf("%lf%d", &x, &exp) == 2) : scanf()는 2개의 값을 읽는데 성공하면 2를 리턴한다.
- scanf()로 입력 받을 시 화이트스페이스는 무시하고 읽는다.
- q를 입력 시 sanf()가 읽을 수 없어 0을 리턴한다. 마찬가지로, "2.8 q"를 입력해도 scanf()는 1을 리턴한다.
'LAB > C' 카테고리의 다른 글
[24.08.10] c언어의 기초8 (0) | 2024.08.10 |
---|---|
[24.08.09] c언어의 기초7 (1) | 2024.08.09 |
[24.08.08] c언어의 기초5(2) (0) | 2024.08.08 |
[24.08.08] c언어의 기초5(1) (0) | 2024.08.08 |
[24.08.07] c언어의 기초4 (1) | 2024.08.07 |