내장형 하드웨어/C언어

무한반복문, break, 포인터

동화다아아 2011. 4. 14. 16:47
 

무한 반복 문


//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라는 값이 선언된다.