로그인하고 있지 않습니다. 편집하면 당신의 IP 주소가 공개적으로 기록됩니다. 계정을 만들고 로그인하면 편집 시 사용자 이름만 보이며, 위키 이용에 여러 가지 편의가 주어집니다.스팸 방지 검사입니다. 이것을 입력하지 마세요!====포인터==== C언어를 배우면서, 조건문, 루프문등 기초적인 문법에 대해서 학습할때까지는 큰 장벽을 못 느끼다가, 포인터로 넘어오면서 C언어를 포기하는 경우가 많다. 그 이유는 앞에서의 문법들은 사실 사람의 말을 배우듯이 따라가면 되는 것이고, 또한 논리적인 추론능력만 충분하다면 컴퓨터를 처음 하는 사람들도 쉽게 배울 수 있다. 하지만, 포인터가 시작되면 거창하게 얘기하면 컴퓨터의 구조, 좁게 보면 메모리의 구조에 대한 이해와 C언어가 메모리를 어떻게 다루는가, 메모리 계층 구조가 어떻게 되는가에 대한 이해가 없다면 포인터의 개념을 이해하고 활용하는 데에 상당한 어려움을 겪게 될 것이다. 다음은 포인터를 사용한 간단한 예시이다. <syntaxhighlight lang="c"> #include <stdio.h> int main() { int a=5; int *pa; pa=&a; printf("%d %d %d",a,pa,*pa); return 0; } </syntaxhighlight> 위의 예제에서 어떤 값이 출력되는지 알아보자. 우선 첫번째 값은 당연히 a가 출력될 것이다. 그러면 2, 3번째 값은 어떤 값이 출력되는가? 먼저, 2번째 값은 <b>a가 저장된 주소</b>가 출력된다. 여기에서 알 수 있듯이 포인터 변수 pa에 저장된 값이 a의 주소임을 알 수 있다. &a가 바로 a의 주소를 나타낸다. 왜 그런지는 다음 단락에 설명하겠다. 그리고 3번째 값은 a의 값인 5가 출력되는데, 왜 그런 것일까? 우선 주소 참조와 관련된 두 가지 연산자를 알아둘 필요가 있다. 이 둘은 이미 위에서 모두 나왔다. 그렇다, &과 *이다. 이 두 연산자의 사용법은, 변수명 앞에 이 두 연산자를 붙이는 것이다. 이 둘의 기능은 정반대라고 생각하면 되는데, &를 사용할 경우 결과는 그 변수가 저장되어 있는 주소가 되고, *를 사용할 경우 결과는 그 변수에 저장된 주소값에 위치한 변수에 저장된 값이 된다. 즉 간단히 말하자면 *의 경우 변수에 저장된 주소값을 통해 다른 변수를 참조하게 해주고, &의 경우 그 반대의 기능을 수행하는 것이다. 그래서 *을 참조 연산자, &의 이름을 역참조 연산자라고 부르기도 한다. 이제 포인터에 대한 기본적인 내용을 익혔으니 그 응용으로 넘어가 보자. *array를 이용한 string <syntaxhighlight lang="c"> #include <stdio.h> int main() { char str[20] = "hello? librewiki!\n"; printf("%s",str); str[5] = '!'; str[16] = '?'; printf("%s",str); return 0; } </syntaxhighlight> *pointer를 이용한 string <syntaxhighlight lang="c"> #include <stdio.h> int main() { char *str = "hello? librewiki!\n"; printf("%s",str); str[5] = '!'; str[16] = '?'; printf("%s",str); return 0; } </syntaxhighlight> 이 중에서 어느 프로그램은 정상적으로 작동하고 어느 프로그램은 런타임 에러가 걸리는지 이해 하기 힘들 것이다. 메모리의 구조는 크게 5개의 영역으로 나뉜다. CODE, DATA, BSS, HEAP, STACK 일단 이것을 두개로 쪼개면 컴파일시 결정되는 CODE, DATA, BSS(CODE는 프로그램의 코드, DATA,BSS는 전역변수와 문자열 static 변수들이 저장된다. 완전히 정확한 것은 아니지만 ROM영역이라 실행 이후에는 접근 권한이 없다고 생각 하면 된다.) 실행 하는 동안에(Run time동안에)결정되는 HEAP, STACK 그리고 (stack은 지역변수들이 저장되고, HEAP은 동적 메모리이다. 이곳은 RAM영역이다.) 일단, 첫번째 소스가 왜 작동이 잘되는 이유를 알아보자. 일단 문자열은 DATA영역에 컴파일이 되면서 먼저 기록되고, char array는 main함수 안에 있으므로 stack영역에 들어있다. char array는 실제 메모리의 연속된 덩어리 이므로 여기에 DATA영역에 있던 문자열을 그대로 복사하는 것이다. 그렇기에 실제 "hello? librewiki!\n" 라는 문자열은 지금 stack 과 data 영역 모두에 존재라게 된다. 그렇기에 str[5]= '!'; 이런식으로 접근하여 수정해도 아무런 오류가 없다. 하지만 두번째 소스에서 char *str = "hello? librewiki!\n"; 이 선언은 포인터 즉, DATA 에 있는"hello? librewiki!\n" 문자열의 주소만을 가져 온것이다. 실제 stack영역에은 DATA영역의 "hello? librewiki!\n" 주소만 있지, 실제 이 문자열 내용은 존재 하지 않는다. 그렇기에 str[5]= '!' 로 접근하는 것은 ROM영역을 침범한다는 뜻이므로 런타임 에러가 나는 것이다. 요약: 리브레 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포됩니다(자세한 내용에 대해서는 리브레 위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요. 글이 직접 작성되었거나 호환되는 라이선스인지 확인해주세요. 리그베다 위키, 나무위키, 오리위키, 구스위키, 디시위키 및 CCL 미적용 사이트 등에서 글을 가져오실 때는 본인이 문서의 유일한 기여자여야 하고, 만약 본인이 문서의 유일한 기여자라는 증거가 없다면 그 문서는 불시에 삭제될 수 있습니다. 취소 편집 도움말 (새 창에서 열림) | () [] [[]] {{}} {{{}}} · <!-- --> · [[분류:]] · [[파일:]] · [[미디어:]] · #넘겨주기 [[]] · {{ㅊ|}} · <onlyinclude></onlyinclude> · <includeonly></includeonly> · <noinclude></noinclude> · <br /> · <ref></ref> · {{각주}} · {|class="wikitable" · |- · rowspan=""| · colspan=""| · |} {{lang|}} · {{llang||}} · {{인용문|}} · {{인용문2|}} · {{유튜브|}} · {{다음팟|}} · {{니코|}} · {{토막글}} {{삭제|}} · {{특정판삭제|}}(이유를 적지 않을 경우 기각될 가능성이 높습니다. 반드시 이유를 적어주세요.) {{#expr:}} · {{#if:}} · {{#ifeq:}} · {{#iferror:}} · {{#ifexist:}} · {{#switch:}} · {{#time:}} · {{#timel:}} · {{#titleparts:}} __NOTOC__ · __FORCETOC__ · __TOC__ · {{PAGENAME}} · {{SITENAME}} · {{localurl:}} · {{fullurl:}} · {{ns:}} –(대시) ‘’(작은따옴표) “”(큰따옴표) ·(가운뎃점) …(말줄임표) ‽(물음느낌표) 〈〉(홑화살괄호) 《》(겹화살괄호) ± − × ÷ ≈ ≠ ∓ ≤ ≥ ∞ ¬ ¹ ² ³ ⁿ ¼ ½ ¾ § € £ ₩ ¥ ¢ † ‡ • ← → ↔ ‰ °C µ(마이크로) Å °(도) ′(분) ″(초) Α α Β β Γ γ Δ δ Ε ε Ζ ζ Η η Θ θ Ι ι Κ κ Λ λ Μ μ(뮤) Ν ν Ξ ξ Ο ο Π π Ρ ρ Σ σ ς Τ τ Υ υ Φ φ Χ χ Ψ ψ Ω ω · Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ · Ϊ ϊ Ϋ ϋ · ΐ ΰ Æ æ Đ(D with stroke) đ Ð(eth) ð ı Ł ł Ø ø Œ œ ß Þ þ · Á á Ć ć É é Í í Ĺ ĺ Ḿ ḿ Ń ń Ó ó Ŕ ŕ Ś ś Ú ú Ý ý Ź ź · À à È è Ì ì Ǹ ǹ Ò ò Ù ù · İ Ż ż ·  â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û · Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ · ǘ ǜ ǚ ǖ · caron/háček: Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž · breve: Ă ă Ğ ğ Ŏ ŏ Ŭ ŭ · Ā ā Ē ē Ī ī Ō ō Ū ū · à ã Ñ ñ Õ õ · Å å Ů ů · Ą ą Ę ę · Ç ç Ş ş Ţ ţ · Ő ő Ű ű · Ș ș Ț ț