디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

늅늅이가 쓰는 늅늅이를 위한 C언어 포인터강좌 .....-1부-

태연여신님갤로그로 이동합니다. 2009.06.19 23:13:38
조회 3745 추천 1 댓글 10


- 본강좌에 나오는 예는 C언어 기반으로 작성되었음.
- 본강좌는 늅늅이가 쓰는 늅늅이를 위한 포인터 개념설명 강좌로 용어설명이 틀리거나 내용이 틀릴수 있음. (지적바람)


1. 포인터를 설명하기 앞서 기억해야하는 기본 C언어 문법


1) 변수 선언

      int a;
      - int (정수)형 데이터를 선언함. 여기서 선언의 의미는 명시적으로 컴파일러에게 변수명인 a를 사용한다는것과 컴파일시 
        4바이트의 메모리영역을 할당한다는 뜻.
      - char(문자)형(1바이트), float(실수)형(4바이트) 등의 선언도 같은 맥락.
      - 궁극적으로 프로세스가 변수의 메모리영역을 할당하는 이유는 운영체제가 효과적으로 메모리 관리를 해야하기 때문.
      - 내가 작성한 C코드를 실행한 프로세스는 현재 실행중인 다른 프로세스의 변수 메모리영역에 침범하거나, 침범당하지 않
         아야한다.
      - 이를 운영체제가 메모리영역을 할당한다는 개념으로 다른프로세스와의 메모리 충돌을 막는다.


2) 리터럴(literal)

      - 리터럴이란 값그자체로 상수의 개념이지만 실제로 메모리가 할당되지않는 값들을 말한다.
      - 예를들어 a = 10; 라는 문장이 있을때 a는 변수, =는 연산자, 10은 리터럴이다.
      - 단 문자열상수는 메모리가 실제로 할당되어 저장되며, 단 이메모리 영역은 read only이다.
      - 따라서 int *ptr; ptr=&"hello"; 라는 연산도 가능하긴 하다. 다만 쓸모가 없다.


 3) 연산자

   ① 대입연산자 = : 대입연산자는 rvalue(우측값)에서의 연산의 결과를 lvalue(좌측값)에 대입시키는 연산이다. 이때 
       lvalue은 반드시 메모리가 할당되있는 영역이어야 하며 좌변값과 우변값은 반드시 같은 타입이어야 한다.
      - ex1-1) int a =10;
      - ex1-2) 10 = a; (대입되는 lvalue가 메모리가 할당되지않는 리터럴이므로 당연히 안된다.)
      - ex1-3) int a=10,b=20; a=b; (우측값은 변수라도 대입이 된다.
    ② 주소연산자 & : 주소연산자는 보통 변수에 쓰며, 변수의 메모리 시작주소를 나타낸다.
       - ex1-4) int a,*ptr; ptr=&a; (포인터변수 ptr에 a의 메모리주소를 담는다)
    ③ 참조연산자 * : 참조연산자는 가르키는 주소의 값을 나타내는 연산이다. 당연히 포인터에서 사용된다.
       - ex1-5) int a=10,*ptr=&a; (정의문에서 *는 참조연산이 아니다. 포인터 선언문이다.)
          printf("%d",*ptr); (ptr에 저장된 주소 (a의 주소)의 값을 출력한다.
    ④ 캐스팅연산 (데이터형) : 변수앞에 캐스팅연산을 사용하면 그값은 강제로 해당데이터형으로 변환된다. 단 정보손실이 생
        길수 있으니 신중히 사용해야한다.
        - ex1-6) float a=10.10; int b=(int)a;
    ⑤ sizeof(변수명 혹은 데이터형) : 해당 변수 혹은 데이터형의 크기를 나타내는 연산이다.
        - ex1-7) int a; printf("%d",sizeof(a)); 결과는 변수 a의 메모리크기
        - ex1-8) printf("%d",sizeof(int)); 결과는 int형의 메모리크기
 
2. 포인터 변수란?


    - 일반적으로 변수란 어떠한값을 지속적으로 저장하여 변경,이용하기 위해 메모리영역을 할당하여 사용하는 것들로 변수를
        자료형태에 따라 정수형,실수형,문자형이 있다.
    - 포인터 변수도 마찬가지로 변수이며, 변수에 저장할수있는 타입으로 정수,실수,문자형이 있는것과 마찬가지로 포인터
        정수는 메모리의주소를 담기위한 변수이다.
    - 메모리주소는 32bit 기반의 운영체제를 기준으로 4byte이므로 (8bit는 1byte, 32bit는 4byte) 포인터변수는 실제로 4바
       이트가 선언시 할당되며 정수형을 담는 변수이다.
    - 따라서  char *형이든 int *형이든 void *형이든 모든 포인터변수는 4바이트크기를 갖으며 정수를 저장하는 변수인것이다. 
    - char *, int *, void *등  포인터변수의 데이터형은 포인터변수의 크기와는 관련이 없고 주소를 대입받는 변수의 자료형
      과  포인터연산과 관련이 있다.


3. 포인터변수 선언 및 정의

    - 포인터변수의 선언은 일반변수 선언식에서 변수명앞에 *기호를 첨부하면서 이루어진다.
        ex3-1) int *ptr;
     - 포인터변수는 리터럴상수로의 직접적인 대입이 불가능하다. 이는 사용자가 직접 주소를 입력하여 사용할경우 발생되
        는 여러가지 메모리영역에서의 문제를 컴파일러 차원에서 방어하기 위함이다.
     - 보통 포인터값을 당장 사용하지 않을경우 NULL 값을 넣기도 한다.
     - 포인터변수의 정의는 주소의 대입으로 이루어진다.
          ex3-2) int *ptr,a=10; ptr=&a;


4. 배열의 선언 및 정의


    - 배열은 같은타입의 데이터를 메모리상 연속되게 나열하여 할당하는 데이터형이다.
    - 보통 배열의 선언은 일반변수 선언식에서 [SIZE]를 첨가하여 선언한다.
         ex5-1) int arr[10];
    - 여기서 SIZE는 반드시 리터럴상수중에 양의정수로만 와야하며, 변수로의 대입은 불가능하다. (매크로상수는 가능)
     - 배열의 정의는 { } 괄호로 각각 정의할수 있으며, 문자열의 경우 "내용"으로 선언시에만 대입할수 있다.
         ex5-2) char arr[10]={\'h\',\'e\',\'l\',\'l\',\'o\',\'\\0\'};
         여기서 \'\\0\'는 숫자 0과 완전이 똑같으며, 보통 매크로로 NULL이라고 정의하기도 한다. NULL또한 1바이트를 차지하
         는 데이터이다.
          ex5-3) char arr[10]="hello";
         여기서 NULL을 첨가하지않아도 자동으로 들어간다, 따라서 문자형 배열선언시 문자수+NULL의 1바이트를 고려하여
        야 한다.
    - 선언이후에 문자열 대입연산은 불가능하다. 따라서 이런경우에는 strcpy() 함수를 사용한다.
    - 일일이 대입이 귀찮을 경우 규칙이 있거나, 복사하기 위하여 for문을 이용하여 대입하기도 한다.
    - 배열의 이름은 배열의 시작주소 그자체이다. (따라서 scanf같이 주소연산이 필요한 함수에 배열을 인자로할때 절대 주
        소연산(&)을 쓰면안된다.)
    - 따라서 이런식도 당연히 가능하다.
         ex5-4) int arr[10]={1,2,3,4,5}, *ptr; ptr=arr;


5. 포인터 연산

    - 포인터의 산술적인 연산은 상식수준에서 생각할 필요가 있다.
    - 일단 포인터끼리의 대입연산은 가능하다, 하지만 리터럴의 대입은 불가능하다. (위에서 설명)
    - 포인터값끼리의 덧셈연산은 불가능하다. 즉 주소값+주소값의 연산은 불가능하다는 소리다. 이는 그결과가 아무런 의미
        가 없기 때문이다.
    - 단, 포인터와 리터럴의 덧셈연산은 가능하다. 이는 상수만큼 떨어진 메모리주소를 나타내는것을 표현하는데 사용된다.
         ex6-1)  (ex5-4의 내용을 포함해서..) *(ptr+2);는 arr[2](혹은 ptr[2])와 결과가 같다.
    - 포인터끼리의 뺄샘연산은 가능하다. 즉 주소값-주소값의 연산이 가능하다는 소리다. 이는 배열같은 순차구조에서 각자
        료가 떨어진 크기를 말하므로 의미있는 값이기 때문이다.
         ex6-2) int arr[10]={1,2,3,4,5},*ptr1,*ptr2,a; ptr1=&arr[4]; ptr2=&arr[2]; a=ptr1-ptr2; 
    - 포인터와 상수의 뺄샘연산은 가능하다. 하지만 고려할 사항이 있는데, 포인터에 대입된 주소가 어떠한 변수 혹은 배열
        의 시작주소라면 불가능하다. 왜냐하면 배열의 크기는 음수가 될수 없기 때문이다.
    - 당연한 이야기지만 포인터끼리 혹은 포인터와 상수의 곱셈, 나눗셈, 나머지연산과 실수와의 연산은 불가능 하다. (사용
        되지 않는다.)
    - 산술적인 연산을 제외한 비교,논리,대입,캐스팅 연산등은 가능하다.
          ex6-3) if (ptr == NULL)
    - 아까 포인터를 설명하던중 char* , int*, void*식의 자료형이 사용되는 이유를 궁금해할 사람들이 많을것이다.
    - 실제로 int *형 포인터인경우 포인터의값+1은 실제로 주소값에서 4바이트번지 떨어진곳을 나타나여 4가 증가하며, -1
        은 주소값의 4바이 트이전을 나타내여, 즉 4가 감소하는 것이다.
    - 마찬가지로 char *형 포인터인경우 포인터의값+1은 실제로 1의 증가, 포인터값-1은 1의 감소이다.


-2부 계속-

추천 비추천

1

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 경제관념 부족해서 돈 막 쓸 것 같은 스타는? 운영자 24/05/13 - -
143993 횽들 죠낸 뻘질문인건 알지만 난 조ㅅ또 모르거든.. [10] 멍곰.c갤로그로 이동합니다. 09.08.16 122 0
143992 프겔 정전에 대한 오사카의 공식 입장 [3] 분당살람갤로그로 이동합니다. 09.08.16 107 0
143991 정전 프갤 [1] prismatic갤로그로 이동합니다. 09.08.16 43 0
143989 야이 병삼들아! [1] sh(118.218) 09.08.16 57 0
143988 인간은 달에 간 적이 없대 [4] 분당살람갤로그로 이동합니다. 09.08.16 133 0
143985 노트북이랑...데탑이랑 발열 많이 차이남? [2] (115.140) 09.08.16 76 0
143984 서로 다른 남과 여 [6] Vita500갤로그로 이동합니다. 09.08.16 138 0
143982 프갤 정ㅋ전ㅋ [3] 아주아슬갤로그로 이동합니다. 09.08.16 63 0
143981 주석에서 TODO: 하고 쓰는건 무슨 의미야? [6] 오페라(58.237) 09.08.16 171 0
143979 노트북 개념좀.. [1] 싑싑(115.137) 09.08.16 90 0
143978 최근 정보처리기사 어려워짐? [1] 컹곰(124.80) 09.08.16 88 0
143977 형들 itstar알바가모야 ㅁㄵ(218.154) 09.08.16 30 0
143976 16:9형 노트북...어떤가여? (115.140) 09.08.16 49 0
143974 드리프트ㅋ apl(118.39) 09.08.16 44 0
143973 으악!! 이제 몇달 남지 않았어 [3] DMW(123.111) 09.08.16 148 0
143972 비주얼 어시스트 쓰는횽?! 기간만료됐는데 ㅠ,.ㅠ [2] ㅁㄴㅇㄹ(125.188) 09.08.16 100 0
143970 곽한구횽은 봅니다. [3] Vita500갤로그로 이동합니다. 09.08.16 87 0
143968 비타형 소스 올려봅니다 [5] 곽한구(58.237) 09.08.16 107 0
143967 저기 횽들 pmp사서 코딩좀 해볼까 하는데 [1] 막눈(59.28) 09.08.16 74 0
143966 프갤에는 이상하게 고등학생, 대학생이 많은거 같다. [11] Vita500갤로그로 이동합니다. 09.08.16 225 0
143965 이 오류 뭐임? [3] 곽한구(58.237) 09.08.16 83 0
143964 주말을 맞이해 전설거신 이데온을 보고 있다능 [1] 분당살람갤로그로 이동합니다. 09.08.15 61 0
143962 RFB Protocol... 물남(220.125) 09.08.15 201 0
143960 횽들.. 50만원짜리 리눅스는 모임? [3] 멍곰(125.208) 09.08.15 125 0
143959 비스타로 나온 제품을 XP로 바꿀수 있나? [3] (121.173) 09.08.15 69 0
143958 판타지 세계에 등장하는 드래곤 4종 [5] DMW(123.111) 09.08.15 148 0
143956 스미골님 글 읽고 궁금한데요 [2] 군대지원(222.101) 09.08.15 100 0
143955 팊보살님 유리한갤로그로 이동합니다. 09.08.15 28 0
143954 경향신문 홈페이지를 시작페이지로 설정했는데, 프로그래밍에 오류가. [5] 냐옹_갤로그로 이동합니다. 09.08.15 107 0
143953 변수 사용하면... [6] C언어변수(219.251) 09.08.15 107 0
143952 버박 밀어버렸다 [6] DMW(123.111) 09.08.15 163 0
143951 게임회사에 이번에 신입으로 취직했는데요 [3] ㅡㅡ(116.36) 09.08.15 223 0
143950 롸임과 플러우가 없네요 [2] prismatic갤로그로 이동합니다. 09.08.15 90 0
143949 노트북 사는데 추천좀해주세요 [2] 오?오!(121.173) 09.08.15 82 0
143947 와~얼굴이 벌겋게 익었다 이모군(210.218) 09.08.15 62 0
143946 [바캉스] 휴... 포멧 후 Windows 7으로 갈아탔는데... [3] 쿼EI갤로그로 이동합니다. 09.08.15 137 0
143945 흠 Get(Set)Pixel이 느린건가 루프 많이 하는게 병맛인가.. [5] 양희철갤로그로 이동합니다. 09.08.15 172 0
143944 [수영] 윈도우 전체에서 키보드 입력 판단법! 알려주세요 [winapi] [3] GGC갤로그로 이동합니다. 09.08.15 80 0
143943 IDE.. 뭐쓰세요? [8] 눈팅족갤로그로 이동합니다. 09.08.15 175 0
143942 악 횽들 디버깅 질문이요(비트연산자) ㅠㅠㅠ [8] 헬로월드(128.134) 09.08.15 86 0
143941 어..... 무서워.... ㅠ-ㅠ [1] algorithm갤로그로 이동합니다. 09.08.15 79 0
143940 리젠 ㅇㄴㅁ(218.233) 09.08.15 29 0
143939 허경영을 불러봐 [1] 유리한갤로그로 이동합니다. 09.08.15 125 0
143938 예비역 병장인 내가 현역들에게 말한다 [4] 유리한갤로그로 이동합니다. 09.08.15 181 0
143936 /레그/ 오랜만에 늘어지게 잤다 DMW(123.111) 09.08.15 54 0
143935 일찌감치 공무원준비 케케켁켁갤로그로 이동합니다. 09.08.15 54 0
143934 리본 메뉴 [5] NaCl갤로그로 이동합니다. 09.08.15 121 0
143930 취업갤러리 글인데 이거 정말 사실임? [2] 뉴비(124.80) 09.08.15 153 0
143929 채팅이다 접속해라 수직하락갤로그로 이동합니다. 09.08.15 49 0
143926 SQL 쉬운게 아니었군효 algorithm갤로그로 이동합니다. 09.08.15 94 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2