무한반복문, break, 포인터
무한 반복 문
//1에서 100 사이의 짝수를 한 줄에 다섯 개씩 출력하는 프로그램
#include<stdio.h>
int main()
{
int i;
for(i=1;i<=100;i++)
{
if(i%2==0)
{
printf("%5d",i);
if(i%10==0)
{
printf("\n");
}
}
}
return 0;
}
⇒ 흐름도
break 문
⇒ break 문은 반복문이나 switch 문에서 사용된다. 반복문 내에서 break 문이 사용되었을 경우는 반복문을 종료시키고, 그 다음 명령문을 실행시킨다. switch 문에서도 같은 역할을 하여 switch 문의 실행을 종료시키고 그 다음 명령문으로 제어를 넘긴다.
// q를 입력받을 때까지 문자를 화면에 출력하는 프로그램
#include<stdio.h>
int main()
{
char ch;
printf("enter any character <q to quit> : ");
while(1)
{
if((ch =getchar()) == 'q')
{
break;
}
putchar(ch);
}
printf("\nEnd of program\n");
return 0;
}
포인터의 개념과 텍스트 파일
⇒ 컴파일러는 변수에 메모리를 할당하고, 할당된 메모리와 변수를 연결시켜준다. 여기서 변수와 할당된 메모리, 그리고 메모리 주소와의 연결방법을 알아야 한다.
// 변수의 값과 주소를 출력하는 프로그램
#include<stdio.h>
int main()
{
int x;
x=25;
printf("the value of x: %d\n\n",x);
printf("the address of x: %p\n",&x);
return 0;
}
⇒ 변수 x의 주소값을 확인해보면
→ linux에서 x:25 일때 주소값은 0xbffff868
→ window에서 x:25 일때 주소값은 0x012ff71
→ 형식 지정자 %p는 16진수 메모리 주소를 출력하게 한다.
→ &(ampersand)는 주소연산자로 &x는 변수가 할당받은 메모리의 주소를 말한다.
→ 변수가 할당받은 메모리의 위치는 이 함수의 실행이 끝날 때까지 변하지 않는다.
⇒ 각각의 운영체제는 각자의 방식으로 가상의 메모리 공간을 만들어서 변수를 실행시켜 준다.
// 포인터 변수의 선언과 사용을 보여주는 프로그램
#include<stdio.h>
int main()
{
int x;
int *xp; // xp는 int 형의 포인터변수로 선언됨
x=7; // 변수 x를 7로 초기화
xp=&x; //변수 xp를 x의 주소값으로 초기화
printf("address of x: %p\n",&x); // 변수 x의 주소
printf("value of x: %d\n",x); // 변수 x의 값
printf("address of xp: %p\n",&xp); // 포인터 변수 xp의 주소
printf("value of xp: %p\n", xp); // 포인터 변수 xp의 값 → &x)
printf("value of *xp: %d\n",*xp); // xp가 가리키는 곳의 값 → x=7)
return 0;
}
⇒ 출력결과
⇒ symbol table
type |
name |
address |
int |
x |
BFFFF868 |
int *(int 형 포인터) |
xp |
BFFFF864 |
]
→ xp는 정수를 저장한다.(주소는 음수가 없다. 즉, unsigned 정수형을 저장한다.)
→ 결국 pointer는 양수 숫자를 저장한다.(주소값을 저장한다.)
→ 만약 x=8; xp=8; 이라고 선언한다면 xp=8;에서 경고가 뜬다.
assignment
→ xp에는 BFFFF868의 주소값(x의 주소값)이 들어간다. (xp=&x)
→ *x=7; 이라고 쓸 수 없다.(error) 여기서 *는 다항연산자 즉, 곱셈으로 인식한다.
→ *xp=7; error가 아니다.(심블 테이블에 선언된 *개수만큼 *를 사용할 수 있다.) 여기서 *는 포인터를 뜻한다.
→ int **p; 는 선언이고 **p는 사용이다. (→ 차이가 있다.)
→ *xp=7p 은 xp의 주소를 따라가라(*)는 뜻이다
즉, BFFFF868로 가서 주소값의 자리인 x에 있는 값을 찾는다.
⇒ 다시한번 정리해 보면
symbol table
type |
name |
address |
int |
x |
5000 |
int* |
xp |
5004 |
라고 한다면.
→ x=100; //을 주었을 때.
→ xp=&x; //라 하면 (&x는 5000이다.)
이것은 xp=5000(→주소값) 라는 말과 같다.
→ *xp=33; //이라고 선언한다면
이것은 *5000=33; 이라는 말과 같다.
→ 따라서 x=33 이 된다.
⇒ 캐스팅 사용
→ * 0xBFFFF868 = 55; // 라고 하면 에러이다. 왜냐면 주소값 BFFFF868을 컴퓨터는 아직소 숫자로 입력하고 있기 때문이다. 따라서 casting을 통하여 정수로 취급하게 해야 한다.
→ *(int*)0xBFFFF868 = 55; // 에러가 아니다. 캐스팅(0xBFFFF868)을 int 형 주소값으로 보겠다고 선언했기 때문에 주소 BFFFF868에 55라는 값이 선언된다.
'내장형 하드웨어 > C언어' 카테고리의 다른 글
포인터 - 포인터 변수가 가리키는 자료형의 의미, 세그먼테이션(segmentation) (0) | 2011.04.18 |
---|---|
포인터 변수의 변화, 주소 저장 방식 - Big Endian, little Endian (1) | 2011.04.15 |
for문 (초기식과 증감식의 변형, 무한반복문) (0) | 2011.04.13 |
VMware player 설치, 리눅스 명령어 (0) | 2011.04.11 |
for 문 - 초기식, 조건식, 증감식, volatile, 최적화 (0) | 2011.04.11 |