내장형 하드웨어/C언어

#define, 함수 인자, 반환(return, printf)

동화다아아 2011. 4. 22. 13:34
 

#define 문


// 원의 둘레를 계산하는 프로그램

#include<stdio.h>

#define PI 3.1416

int main()

{

        int radius; // 원의 반지름

        float circumference; // 원의 둘레

        radius = 5;

        printf("The radius of circle is %d m\n",radius);

        circumference=(radius + radius)*PI;

        printf("the circumference of circle is %7.2f m.\n", circumference);

        

        return 0;

}

⇒ 실행 결과

        

 

 → 이 프로그램 내에서 PI라는 식별어의 값을 3.1416으로 정의한다는 뜻.

 → 상수값 대신 PI라는 식별어를 사용함으로써 프로그램의 이해가 쉬워지며, 프로그램 내의 여러곳에서 사용되었을 경우 3.1416이라는 값을 수정할 때 #define 문에서만 수정하면 된다.

 → gcc -v --save-temps p1_6 p1_6.c 를 하여 중간 파일을 삭제하지 않고 확인할 수 있다.

⇒ #define PI 3.1416 과 float PI = 3.14f; 의 차이

  → #define PI 3.1416 는 전처리 단계에서 적용되어 메모리를 차지하지 않는다.

  → float PI = 3.14f;는 메모리를 차지한다.

  → 최적화를 위해서는 #defined를 쓰는 것이 좋다. 하지만 C++에서는 권장하지 않는다. 

 → #define 는 컴파일 단계에서 전처리 파일(.i)로 포함된다.

 

 → 전처리 파일(.i)를 읽어 보면 이렇게 #define 문이 사라지고 PI가 3.1416으로 모두 바뀌어 있는 것을 확인할 수 있다.


※ 옵션 복습.

  -v → 컴파일 과정을 화면에 출력한다.

  --save-temps → 컴파일 과정에서 생성되는 중간 파일인 전처리 파일(*.i)과 어셈블리 파일(*.s)를 지우지 않고 현재 디렉토리에 저장한다. 컴파일 과정의 에러를 분석할 때 사용.


⇒ gcc -DPI=3.1416 -o p1_6 p1_6.c

  → 컴파일을 시작할 때 #define PI 3.1416을 적용시켜 컴파일 해준다.

⇒ makefile에서

  → CFLAGS =-DPI=3.1416


Compiler C: main.c

⇒ mmcu = atmega128 → CPU를 atmega128로 컴파일 해준다.

⇒ I. → 소스와 같이 있는 파일을 include 한다는 뜻.




#include<stdio.h>

void test(int iNum);

int main()

{

        test(7);

        test(8);

                        

        return 0;

}


void test(int iNum)

{

        printf("%d\n",iNum);


        return;

}

⇒ 실행 결과

 


- 함수내 변수 중복에 관련된 에러 확인하기

 


⇒ void test(int iNum) 함수 안에 만약 int iNum을 다시 선언하면 중복되어 컴파일하면.

 → hello.c:13: warning: declaration of 'iNum' shadows a parameter 라는 경고가 뜬다.

 

→ 이것은 iNum이 인자에 하나, 함수 내의 중괄호 안에 하나 더 선언되어 겹쳐지나 컴파일러가 인자와 중괄호 내의 차이로 인해 가장 최신(중괄호) 안의 iNum을 참조하므로 실행은 되나 경고를 출력한다.

→ 만약, void test(int iNum) 함수 안에 int iNum을 두번 선언하면 에러가 발생한다.

→ 이것은 중괄호 내에 iNum의 두 번 선언이므로 에러로 취급된다.


-인자를 두 개로 선언하면

#include<stdio.h>

void test(int iNum1,int iNum2);

int main()

{

        test(7,8);

        return 0;

}

void test(int iNum1,int iNum2)

{

        printf("%d %d\n",iNum1,iNum2);

        printf("%d %d\n",iNum2,iNum1);

        return;

}

⇒ 실행결과


⇒ 위의 소스에서 에서 함수선언에 void test(int ,int ); 라고 선언하면 int 의 이름을 각각 어떤 것으로 하거나 공백으로 두더라도 에러가 발생하지 않는다. 컴파일러는 컴파일 과정에서 함수선언에서 symbol table에 함수의 이름을 참조하고, 인자의 타입만을 참조하기 때문이다.


⇒ return → main 함수로 되돌아간다.

   return → 1000을 가지고 main 함수로 되돌아간다.

  → 그것은 즉, test(7,8);이 1000;이 된 것과 같다.


#include<stdio.h>

int test(int iNum1,int iNum2);

int main()

{

        int iRet;

        iRet=test(7,8);


        printf("%d\n",iRet);

                        

        return 0;

}


int test(int iNum1,int iNum2)

{

        printf("%d %d\n",iNum1,iNum2);

        printf("%d %d\n",iNum2,iNum1);


        return 1000;

}

⇒ 실행결과

 → return은 main 함수로 되돌아 간다는 뜻이다.

 → return 1000; 은 1000을 가지고 돌아간다는 뜻.

 → 즉, test (7,8); 은 1000;과 같다. 결과에 영향을 미치지 않는다.

 → iRet=test(7,8);

    printf("%d\n",iRet);

    로 선언하여 반환된 1000값을 확인 할 수 있다.


#include<stdio.h>

int test(int iNum1,int iNum2);

int main()

{

        int iRet;

        iRet=printf("12345\n");

        printf("%d\n",iRet);

        return 0;

}


int test(int iNum1,int iNum2)

{

        printf("%d %d\n",iNum1,iNum2);

        printf("%d %d\n",iNum2,iNum1);


        return 1000;

}

⇒ 실행결과

 → printf도 반환된다.

 → iRet=printf("12345\n");

    printf("%d\n",iRet);

    로 선언하여 반환된 printf를 확인할 수 있다.

 → printf는 화면에 몇 글자(개행 문자 포함)를 찍었는지를 반환한다.