|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


3198, 1/160 |
![]() |
![]() |
![]() |
![]() |
|
thunder994 | ||||||
|
C언어 초보인데 잘못된 부분좀 알려주세요 ㅜㅜ | ||||||
|
http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=3228 [복사]
Hit : 5085 Date : 2011/12/03 05:40
|
|||||||
| ![]() |
| |
| hipro | 포인터 관련인듯... 큭.. 난 모르겠어요 ㅋㅋㅋㅋㅋ | 2011/12/03 | |
| prosthetics | /* 안녕하신가? 나는 프로그래밍 관련 질문 게시판에 서식하는 Prosthetics라고 하네. 주로 C, C++, C#, Java 등의 언어에 대해 답변을 하네. 뛰어나게 잘해서 답변하는건 아니고, 답을 하다보면 내 실력도 올라가니까 겸사겸사 답을 하고있네. 하여튼 막히는게 있을때 여기다가 물어보면 내가 답해줄 걸세. 본론으로 들어가지. 포인터는 주소를 저장하고 있는 변수입니다. 값을 저장하는 인트형 변수와 비교를 해보지요. int a = 0; ->a는 값0을 저장하는 int형 변수입니다. ->a는 변수로써, 주소, 값, 이름 등의 속성을 가지는데, a는 이름에 해당하는 것이지요. ->컴퓨터는 주소를 가지고 변수를 구분합니다. 0x12345678같은. ->이걸 사람이 사용하기엔 조금 문제가 있으니까 간단하게 a라고만 해주면 컴파일러가 0x12345678로 바꿔줍니다. 뭐 다 알고있는걸 적어놓은 것 같네요. int* sel=0; -> *은 int에 붙여도 되고, sel에 붙여도 됩니다만 int*이 한세트로 (인트형 포인터 )를 나타내니까 저는 int에 붙이겠습니다. ->그리고 선언과 동시에 초기화할때 ,로 한줄에 연결하는 것보다. 여러줄로 나누는게 읽기 쉽고 정확도도 올라갑니다. 가끔 저렇게 코딩하면 이상하게 프로그램이 돌아가는 경우가 있어요. -> 하여튼 인트형 포인터 sel을 선언하고 거기다가 0을 넣어줬네요. -> 즉, 주소를 담는 변수에 0이라는 주소를 넣어준겁니다. 값을 넣어준줄 알았죠?ㅋ 저도 깜빡 속았다니까요. -> thunder994님이 원하셨던것은 0이라는 값을 저장하는 거였겠죠? 그럼 다음과 같이 바꿔줘야합니다. ->int sel = 0; -> *하고 &의 차이는 알고계실테니 따로 설명안하겠습니다. -> 는 훼이크고. <&변수 : 주소>, <*주소 = 변수> -> int* 변수 = 주소; void input_select(int *sel) -> void로 바꿧습니다. call by reference는 값을 반환하지 않아도 되거든요. -> 매개변수가 int* sel이네요. 바로 위에서 int* 변수 = 주소;라고 했죠? 여기다가 주소를 넣어줘야합니다. -> 그 바로위에는 <&변수= 주소>라고 써져있네요. &sel하면 되겠네요. 수정된 코드는 아래와 같습니다. 오랜만에 질문이 와서 흥분해서 답을 썼는데 보통 이렇게 답변 안합니다.(특히 도입부분) 이제와서 답한거 수정하려니 귀찮아서 그냥 올립니다. 글중에 기분나쁜것 있었으면 사과드립니다. */ #include <stdio.h> void input_select(int *); //int->void void input_num(int *,int *); void select_cal(int *,int *,int *); void add(int *,int *); void sub(int *,int *); void mul(int *,int *); void div(int *,int *); void end(); void main() { // int sel=0; int num1=0; int num2=0; input_select(&sel);//*sel=input_select(sel); if(sel!=5) input_num(&num1,&num2);// select_cal(&sel,&num1,&num2);// } void input_select(int* sel) //int->void { printf("======메뉴를 선택하세요======\n"); printf("=====1.덧셈======\n"); printf("=====2.뺄셈======\n"); printf("=====3.곱셈======\n"); printf("=====4.나눗셈=====\n"); printf("=====5.종료======\n"); printf("==================\n"); printf("연산을 선택하시오 : "); scanf("%d",sel); // return *sel; } void input_num(int *num1,int *num2) { printf("연산할 수를 입력하시오 : "); scanf("%d %d",num1,num2); } void select_cal(int *sel,int *num1,int *num2){ switch(*sel){ case 1: add(num1,num2); break; case 2: sub(num1,num2); break; case 3: mul(num1,num2); break; case 4: div(num1,num2); break; case 5: end(); break; } } void add(int *num1,int *num2){ printf("%d + %d = %d\n", *num1,*num2,(*num1)+(*num2)); } void sub(int *num1,int *num2){ printf("%d - %d = %d\n", *num1,*num2,(*num1)-(*num2)); } void mul(int *num1,int *num2){ printf("%d * %d = %d\n",*num1,*num2,(*num1)*(*num2)); } void div(int *num1,int *num2){ printf("%d / %d = %.4lf\n",*num1,*num2,(double)(*num1)/(*num2)); } void end(){ printf("종료\n"); } |
2011/12/03 | |
| hipro | num1이랑 num2가 void add(int ,int ); void sub(int ,int ); void mul(int ,int ); void div(int ,int ); 로 못가는듯 합니다만은?? |
2011/12/03 | |
| hipro | 아.. 주소값을 이용하면 상관없나요?? 에고고 머리야.;;; | 2011/12/03 | |
| prosthetics | int *sel=0,*num1=0,*num2=0; 위 선언이 "sel,num1,num2가 0이라는 값을 가리킨다"라는 오류에서 시작한 논리 오류입니다. 실제로는 int* sel = NULL;과 같이 0이라는 주소를 대입한 것이니 scanf("%d",sel); 이부분에서 런타임 오류가 나는 것입니다. 0x00000000라는 주소에 값을 저장하려하니까요. 널 포인터 오류라고 하는데 아래 보시면 될겁니다. http://ko.wikipedia.org/wiki/%EC%84%B8%EA%B7%B8%EB%A9%98%ED%85%8C%EC%9D%B4%EC%85%98_%EC%98%A4%EB%A5%98 |
2011/12/03 | |
| hipro | prosthetics님! 고맙습니다 ㅎㅎㅎ 보고 가는 사람마저 배워가는군요! ㅎㅎ | 2011/12/03 | |
| thunder994 | 답변과 친절하신 설명 정말 감사합니다!^^ 그런데 궁금한게있는데요. sel,num1,num2를 아예 포인터 변수로 선언해서 사용할수는 없는건가요? 너무 복잡해질까요?.? 처음부터 포인터형 변수를 선언해서 만들려고 했는데 자꾸 포인터 초기값을 주라고 디버그에 뜨길래 어쩔수없이 그냥 초기값준답시고 0을 넣는다고 했는데 그게 그게 아니었네요..ㅋ 어떻하면 포인터형변수 선언해서 &연산자 없이 완성할수있을지 궁금합니다 ^^; |
2011/12/03 | |
| prosthetics | 주소를 담는 변수이기 때문에 값은 담을 수 없습니다. (int*)형 변수는 int형 변수의 주소밖에 저장할 수 없습니다! int sel = 0; int* ipsel = &sel; input_select(ipsel); 이런식으로는 &의 개수를 최대한 줄이는 것 밖에 안되겠네요~ |
2011/12/03 | |
|
|