본문 바로가기

C

오답노트

 대체 몇번을 다시 하는건지.. 맨날 까먹기만 하고 정리해서 잊어 먹지 안토록 주의하자!!!

 

 관계연산이 논리연산보다 우선순위가 높다. 괄호 사용유무에 상관없이...

ex>   result = (val1==10 && val2 ==12);

      // val1과 val2의 관계연산이 끝나고 나면 && 연산을 해서 result 변수에 값이 대입된다.  난순서대로 되기때문에 괄호를 해야 되는건줄 알았는데 그게 아님!!

 

 삼항 연산자 ... 음 신기하군..

     ex>   x = (y<10)? 10 : 20 

            // y가 10보다 작으면 x에 10 아니면 x에 20을 반환한다.

 

 기본 오류 사항..

     scanf를 사용시 값을 하나씩 입력할때에는 &를 붙인다.. 배열도 마찬가지다.. 하지만 문자열을 입력할때에는 &를 붙이지 않는다.

     배열에 값을 입력할때 정수의 입력에는 " = 정수 "의 방법대로 하면 되지만 문자값 입력시에는 " = '문자' "의 방법으로 해야 된다.

     오류 발생시 너 김형진이 가장 발견못하는 것 중에 하나다..  ex> arr[3][1] = 'a'

     2차원 배열 초기화 해줄때 대괄호 속에 대괄호를 해줘서 초기화 해주어야 한다.

     ex> int arr[3][4] = {

            { 1,2,3,4 },                                                        이렇게 하면   데이터는     1 2 3 4

            { 5,6,7},                            == >                                                              5 6 7 0

            { 9 }                                                                                                     9 0 0 0               이렇게 입력이 된다..

           }

            ** 모 그냥 한줄로 쫙 입력해줘도 되지만 해독성과 편의성을 위해서 대괄호 속의 대괄호 식으로 표현하는게 편하다...

                대괄호 속의 대괄호다 실수하지 말것!!

 

 이중 포인터 : 메인에서 참조하는 싱글 포인터의 값을 바꾸어주기 위해서 함수를 호출할때 같은 싱글형으로 매개변수를 가져오면 메인함수의 포인터는 바뀌지 않는다..

                       이유는 싱글에서 싱글로의 포인터 이동은 참조에 의한 호출이 아닌 값에 의한 호출이기 때문이다. 따라서 호출한 함수가 종료되면 그 함수의 기능및 역할은 모조리 사라진다. 간단하게 값에 의한 호출이기 때문에.. 따라서 메인에서 가리키는 포인터의 주소값을 바꾸고자 함수를 호출할때에는 이중포인터로 메인함수의 싱글포인터를 가리킬수 있도록 설정해주어야 한다.

      ex> 간단한 예재로써는 배열의 최대, 최소값 포인터로 지정 찾아내는것..

 

 2차원 배열 이름은 포인터 연산시 행 단위로 이동을 한다.

       ex> arr[3][2] = {1,2,3,4,5,6};

      일때 arr은 물론 포인터..    arr+1 arr+2 arr+3 = 1, 3, 5 를 가르킨다. 즉.. arr[1][0], arr[2][0], arr[3][0] 을 나타낸다..

 

   배열 포인터와 포인터 배열!!

       int (*pArr)[4]는 배열을 가리키는 포인터, 즉 배열 포인터 이다. int형 변수를 요소로 지니고 포인터 연산 시 4칸씩 이동하는 2차원 배열을 가리키는 포인터이다.

       반면...

       int* pArr[4]는 배열이다..(포인터 배열) int형 변수의 주소값 4개를 저장할 수 있는 배열이다. 즉 포인터 4개..

 

  a[2][1] = *(*(a+2)+1)

      a[1][2] = *(a[1]+2)

      a[1][0] = (*(a+1))[0]               a[i][j] = *(a[i]+j) = (*(a+i))[j] = *(*(a+i)+j)

 

  int *p = int형을 가리키는 포인터

      int* *p = int*형을 가리키는 포인터     앞의 타입은 어떤형태가 가리키는 타입을 나타낸다..

      2차원 배열의 포인터타입 ==> 배열이름이 가리키는 대상과 배열이름을 통해서 포인터 연산 시 이동하는 거리

 

  함수포인터 = 메인 메모리에 올라와 있는 함수를 가리킬 수 있는 포인터

                        함수의 이름은 메모리상에 존재하는 함수의 위치를 가리키는 포인터, 상수포인터에 해당됨

     int (*fPtr1) (int);

    void (*fPtr2) (int, int);  리턴형과 매개변수형이 같은 함수는 어느것이나 호출을 하여 그와 같은 기능으로 사용할수 있다.

    ex>  void SelFunction(int s)

          {                                                          // 입력값 s 에 따라서 Add 나 Min 함수를 대입하여 함수를 수행하도록 해주는 함수 포인터의 예제다..

void (*fPtr) (void);                          // 옵셥의 함수들의 리턴값과 매개변수를 같은형식으로 나주면 유용하게 함수포인터를 써먹을수 있겠다..

 if(s==1)

       fPtr=Add;

 else

      fPtr=Min;

 fPtr();

   }

 

 void 포인터  =  어떠한 무엇이든 담을수 있는 바구니, void 포인터를 선언하면 변수이건, 함수이건, 하다못해 포인터의 주소값까지도 저장이 가능하다..

              좋아보이나;; 값변경, 포인터 연산 등등 안되는게 많다.. 그냥 단지 주소만 저장시킨다..;;(왜있는건지;;;) 주소저장 외에는 아무것도 할 수 없다.

              따라서 연산등에 써먹을려면 명시적(강제) 형변환을 해서 써먹을수 있다. 그러니...

              " 일단 주소 값을 저장해 두고, 포인터의 타입은 나중에 결정한다." 라는 전략으로 사용한다.   또한 '메모리 동적할당'에서 유용하게 쓰인다.

 ex> int n=10;

       void *vp =&n;       // void 포인터 선언 및 초기화

       *vp = 20;             // ERROR

        vp++;                //  ERROR

 

              ex> int n=10;

                    void *vp = &n;        // void 포인터 선언 및 초기화

                    *((int*)vp) = 20;

 

 main 함수를 통한 인자의 전달 ( 가변인자 )

     프로그램 실행시 인자를 전달받을 수 있도록 main함수를 선언하는 것도 가능하며 인자를 전달하는 것도 가능하다.

     ex> int main (int argc, char** argv)

           argc에는 프로그램 명령어를 포함해서 몇개의 인자가 입력됐는지 그 수를 입력해준다.

           argv에서는 배열로써 문자열이 공백을 단위로 나뉘어져 하나씩 argv[] 의 배열값에 들어간다. " "(큰따옴표)로 묶어주면 그 문장을 하나로 인식한다.

    간단한 예제..

    이름과 주민번호를 입력하면 출력해주는 양식

    ex> #include<stdio.h>

            int main(int argc, char **argv)

           {

if(argc!=3)

{

printf("사용 방법 : 파일이름 이름 주민번호\n");

return 1;

}

printf(" 이      름 : %s \n", argv[1]);

printf(" 주민번호 : %s \n", argv[2]);

return 0;

}

 

 Ctrl + Z = EOF    파일의 끝은 -1 이다.

 

  atoi 함수는 배열에 있는 모든 숫자를 하나로 처리해서 넘겨준다. 따라서 배열을 나타내는 포인터 값만 인자로 받아서 해결한다. atoi에 넣어주는 인자를 주의하자.

      ex>
            result = atoi(arr[3]);  (X)

resutl = atoi(arr);       (O)

 

 구조체 변수의 주소값이 첫 번째 멤버의 주소 값과 일치한다.

 

 구조체에서 값을 대입할때 초기화와 동시에 값을 대입하든지 아니면 하나하나 멤버포인터로 대입해주어야 한다.

ex> struct simple s1;                                             

s1={ 10 , 20 };     ( X )                                              struct simple s1 = { 10 , 20 };    ( O )                           

 

 매크로 함수

     장점 : 1. 매크로함수는 자료형에 독립적이다.

  2. 실행 속도가 향상된다.

     단점 : 1. 함수의 크기가 작아야 한다.

  2. 일반적으로 함수를 매크로로 작성시 괄호의 사용이 적절히 이루어 져야 하며 많이 사용된다.

 

 매크로는 1. 그냥 사용하면 문자를 상수로 치환해준다.

                  2. 치환하는 대상앞에  # 을 붙여주면 문자로 치환이 된다.             ex> #define fun(x,y) #x #y

3. 인자와인자사이에 ##을 붙여주면 토큰이 결합되어 나타난다.      ex> #define fun2(x,y) x##y

 

 gets로 입력받은 문자열은 EOF를 리턴하지 않아서 입력받고 문장끝에 문장이 끝났다는 값을 입력해 주어야 한다.

'C' 카테고리의 다른 글

달팽이소스  (0) 2011.01.22
한줄 스왑 코드  (0) 2011.01.22
주석 처리 조건문  (0) 2011.01.22
배열 일정간격으로 나누어서 출력  (0) 2011.01.22
문자열 입력  (0) 2011.01.22