본문 바로가기

C

Call by Reference

Call by Value 로의 함수 호출은 일반적으로 많이 사용해 왔고
그닥 설명이랍시고 달지 않아도 어떤 개념인지 알 듯 하여

주소값(포인터)을 가르키고 그 주소값에 인자를 전달하여 함수를 호출하고
값을 가지고 도는 Call by Reference 프로그램을 작성하여 연습해 본다.

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int Menu(int *j, char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  5. /* int값을 바라보는 포인터로써 *을 써주고, 배열의 인자크기를 선언함으로 2차원 배열임을
    기술하는 의미로
    형선언 후 행을 가르키는 의미로 *와 인자의 크기를 뒤에 기재
    : (*emp_no)=emp_no[] */
  6. {
  7.     int num; /* 지역변수 */
  8.  
  9.     while(1)
  10.     {
  11.         printf(" 메뉴를 선택하세요 ");
  12.         printf("1.리스트 2.검색 3.등록 4.수정 5.삭제 0.종료 : ");
  13.         scanf("%d", &num);       
  14.        
  15.         switch(num)
  16.         {
  17.             case 1:
  18.                 List(j, emp_no, name, gender, jik);
    /* j의 포인터형을 Menu에서 값을 받아와서 j 로 선언 무방 */
  19.                 break;
  20.             case 2:
  21.                 Src(emp_no, name, gender, jik);
  22.                 break;
  23.             case 3:
  24.                 Add(j, emp_no, name, gender, jik);
  25.                 break;
  26.             case 4:
  27.                 Edit(emp_no, name, gender, jik);
  28.                 break;
  29.             case 5:
  30.                 Del(j, emp_no, name, gender, jik);
  31.                 break;
  32.             case 0:
  33.                 system("pause");
  34.                 return 0;
  35.             default:
  36.                 printf("잘못된 번호! ");
  37.         }
  38.     }
  39. }
  40. int ClearEnter(void) /* 엔터버림 */
  41. {
  42.     while(getchar()!='\n');
  43. }
  44. int Add(int *j, char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  45. {
  46.     char ans; /* Yes or No */
  47.     int i; /* 중복체크용 변수 선언 */
  48.     int p; /* 기존 지역변수로 j값을 썼던 것을 대체 */
  49.    
  50.     /* j값을 지역변수로 쓰면 안됨.. */
  51.     for(p=0; p<5; p++) /* 배열의 행값 증가 */
  52.     {
  53.         if(p>4) /* 5개 이상 등록되지 않도록 막음 */
  54.             printf("더이상 입력불가!! ");
  55.         /* emp_no[p]의 값이 NULL과 같다면 0 */
  56.         /* strcmp(s1, s2); : 0(s1=s2), -(s1>s2), +(s1<s2) */
  57.         /* 아래는 !0 : 0이 아니라면, 즉 같지 않다면, emp_no[p]가 빈값이 아니라면 */
  58.         else if(!strcmp("", emp_no[p]))
  59.         {
  60.             while(1)
  61.             { 
  62.                 if(p>4 || strcmp("", emp_no[p]))
    /* emp_no[p]가 빈값이 아니거나 p가 4보다 크다면 */
  63.                     break;
  64.                 printf(" 사번 : ");
  65.                 scanf("%s", emp_no[p]); /* 문자열은 엔퍼센트 연산자를 붙이지 않음 */
  66.                
  67.                 ClearEnter();
  68.                
  69.                 for(i=1; i<5; i++) /* 사번 중복체크 구간 시작 */
  70.                    if(!strcmp(emp_no[p], emp_no[p-i]))
  71.                     {
  72.                         printf("이미 등록된 사번입니다!!");
  73.             /* 이미등록된 사번임을 체크했지만 65행에서 그 값을 입력받았으므로 초기화 함 */
  74.                         memset(emp_no[p],0x00,sizeof(emp_no[p]));
  75.                         return 1;
  76.                     } /* 사번중복체크 구간 끝 */
  77.                 printf("이름 : ");
  78.                 scanf("%20s", name[p]);
  79.                 printf("성별 : ");
  80.                 scanf("%10s", gender[p]);
  81.                 printf("직위 : ");
  82.                 scanf("%20s", jik[p]);
  83.                
  84.                 ClearEnter();
  85.  
  86.                 while(1)
  87.                 {
  88.                     printf("위와같이 등록, 계속 등록하시겠습니까? (Y/N) ");
  89.                     scanf("%c", &ans);
  90.                     if(ans=='y'||ans=='Y'||ans=='\n') /* y or Y or Enter */
  91.                         {
  92.                             (*j)++; /* *j++ : 주소값(e.g.> 0x02...)을 1증가함 */                           
  93.                             break; /* 현재 while문을 빠져나가므로 61행의 while문으로 이동 */
  94.                         }
  95.                     else if(ans=='n'||ans=='N')
  96.                         {
  97.                             (*j)++; /* (*j)++ : j의 주소를 가르키는 값을 1증가함 */
  98.                             return 1;
    /* 현재 함수를 빠져나가고 (현재는)의미없는 1값을 호출한 함수에 반환 */
  99.                         }
  100.                     else
  101.                         printf("잘못된 선택입니다 "); /* 예외 처리 */
  102.                 }
  103.             }
  104.         }
  105.     }
  106.     if(p>4)
  107.         printf("더이상 입력불가!! ");
    /* 5개이상 등록 완료 후 Add()함수 호출시 메시지 출력 */
  108. }
  109.  
  110. int List(int *j, char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  111. /* char (*name)[20] : 2차원 배열의 포인터형 */
  112. {
  113.     int mm; /* 배열의 포인터값 증가 변수 */
  114.     printf(" --- 리스트보기 --- ");
  115.    
  116.     for(mm=0; mm<5; mm++)
    /* 배열의 주소에 값이 없을 때 리스트가 출력되지 않도록 하기 위함 */
  117.     {
  118.         if(strcmp("", emp_no[mm])) /* emp_no[mm]의 값이 NULL이 아닐 때 */
  119.         {
  120.             printf("사번: %-7s >> 이름: %-14s 성별: %-10s 직위: %-10s ", emp_no[mm], name[mm], gender[mm], jik[mm]);
  121.             /* emp_no[mm] : 주소값을 가르킴 */
  122.         }
  123.         else /* emp_no[mm]의 값이 NULL일 때 */
  124.         {
  125.             printf("");
  126.         }
  127.     }
  128.  
  129.     if(*j<=0) /* j 주소의 값이 0이거나 0보다 작을 때 이면 추가되지 않았거나 삭제되어
    데이터가 없을 때 */
  130.     {
  131.         printf("등록된 자료가 없습니다! ");
  132.     }
  133.     printf(" ");
  134.     system("pause");
  135. }
  136.  
  137. int Src(char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  138. {
  139.     char no_src[20]; /* 검색할 사번을 입력받을 1차원 배열의 변수 선언 */
  140.     int k=0, g=0;
    /* k:배열의 주소값을 가르키는 행값 증가용 변수, g:strcmp의 값을 담을 변수 */
  141.  
  142.     printf("검색할 사번을 입력하세요 : ");
  143.     scanf("%s", no_src)
  144.     ClearEnter();
  145.  
  146.     for(k=0; k<5; k++)
  147.     {
  148.        g=strcmp(no_src, emp_no[k]);
  149.  
  150.         if(g==0)
  151.             break;
  152.     }
  153.     if(g>0 || g<0)
  154.     {
  155.         printf("사번을 확인해주세요 ");
  156.         return 1;
  157.     }
  158.     printf(" 해당 사원 찾음 (사원번호: %s) ", no_src);
  159.     printf("조회하신 사원의 정보 입니다 ");
  160.     printf("이름: %-14s 성별: %-14s 직위: %-14s ", name[k], gender[k], jik[k]);
  161. }
  162.  
  163. int Edit(char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  164. {
  165.     char no_edit[20];
  166.     int k=0, g=0, e_num;
  167.  
  168.     printf("수정할 사번을 입력하세요 : ");
  169.     scanf("%s", no_edit);
  170.     ClearEnter();
  171.  
  172.     for(k=0; k<5; k++)
  173.     {
  174.         g=strcmp(no_edit, emp_no[k]);
  175.  
  176.         if(g==0)
    /* g값이 0이라는 것은 입력한 사번과 emp_no[k]의 값이 같다는 것을 의미하므로 */
  177.             break; /* 현재 반복문을 빠져 나가면 아래 while 문으로 이동 */
  178.     }
  179.     if(g>0 || g<0)
  180.     {
  181.         printf("사번을 확인해주세요 ");
  182.         return 1;
  183.     }
  184.     while(1)
  185.     {
  186.         printf(" 해당 사원 찾음 (사원번호: %s) ", no_edit);
                                            /* 입력받은 값과 같은 내용이 있는 */
  187.         printf("조회하신 사원의 정보 입니다 "); /* k행의 배열값을 출력함 */
  188.         printf("이름: %-14s 성별: %-14s 직위: %-14s ", name[k], gender[k], jik[k]);
  189.         printf(" 선택 : 1.이름  2.성별  3.직위  4.모두수정  5.취소 : ");
  190.         scanf("%d", &e_num);
  191.  
  192.         switch(e_num)
  193.         {
  194.             case 1:
  195.                 printf("수정하실 이름을 입력하세요 : ");
  196.                 scanf("%20s", name[k])
  197.                 printf("수정완료! ");
  198.                 printf("수정된 이름 : %s ", name[k]);
  199.                 return 1;
  200.             case 2:
  201.                 printf("수정하실 성별을 입력하세요 : ");
  202.                 scanf("%20s", gender[k]);
  203.                 printf("수정완료! ");
  204.                 printf("수정된 성별 : %s ", gender[k]);
  205.                 return 1;
  206.             case 3:
  207.                 printf("수정하실 직위를 입력하세요 : ");
  208.                 scanf("%20s", jik[k]);
  209.                 printf("수정완료! ");
  210.                 printf("수정된 직위 : %s ", jik[k]);
  211.                 return 1;
  212.             case 4:
  213.                 printf("수정하실 이름을 입력하세요 : ");
  214.                 scanf("%20s", name[k]);
  215.                 printf("수정하실 성별을 입력하세요 : ");
  216.                 scanf("%20s", gender[k]);
  217.                 printf("수정하실 직위를 입력하세요 : ");
  218.                 scanf("%20s", jik[k]);
  219.                 printf(" 수정완료! ");
  220.                 printf("수정된 내용 : 이름(%s), 성별(%s), 직위(%s) 입니다. ", name[k], gender[k], jik[k]);
  221.                 return 1;
  222.             case 5:
  223.                 return 1;
  224.             default:
  225.                 printf("잘못된 번호입니다 ");
  226.         }
  227.     }
  228. }
  229. int Del(int *j, char (*emp_no)[7], char (*name)[20], char (*gender)[10], char (*jik)[20])
  230. {
  231.     char no_del[20]; /* 사번을 입력 받는 1차원 배열 변수 */
  232.     int k=0, g=0;
  233.     char d_ans;
  234.  
  235.     printf("삭제할 사번을 입력하세요 : ");
  236.     scanf("%s", no_del);
  237.     ClearEnter();
  238.  
  239.     for(k=0; k<5; k++)
  240.     {
  241.         g=strcmp(no_del, emp_no[k]);
  242.  
  243.         if(g==0)
  244.         {
  245.             break;
  246.         }
  247.     }
  248.     if(g>0 || g<0)
  249.     {
  250.         printf(" 사번을 확인해주세요!! ");
  251.         return 1;
  252.     }
  253.     while(1)
  254.     {
  255.         printf(" 사원번호: %s ", no_del);
  256.         printf("이름(%s), 성별(%s), 직위(%s) ", &name[k], &gender[k], &jik[k]);
  257.         printf(" 위 자료를 삭제하시겠습니까? (Y/N) : ");
  258.         scanf("%c", &d_ans);
  259.  
  260.         if(d_ans=='y'||d_ans=='Y'||d_ans=='\n')
  261.             {
  262.                 printf("사번(%s)의 %s의 자료가 삭제 되었습니다 ", no_del, &name[k]);
  263.  
  264.                 memset(&emp_no[k],0x00,sizeof(emp_no[k]));
                    /* 0x00 으로 초기화 하여 데이터 삭제 */
  265.                 memset(&name[k],0x00,sizeof(name[k]));
  266.                 memset(&gender[k],0x00,sizeof(gender[k]));
  267.                 memset(&jik[k],0x00,sizeof(jik[k]));
  268.                 (*j)--;
  269.                 break;
  270.             }
  271.         else if(d_ans=='n'||d_ans=='N')
  272.             {
  273.                 return 1;
  274.             }
  275.         else
  276.             {
  277.                 printf("잘못된 선택입니다 ");
  278.             }
  279.     }
  280. }
  281. void HowTo(void)
  282. {
  283.     printf("--- 사원관리 프로그램 --- ");
  284.     printf("사원 관리 프로그램 입니다 ");
  285. }
  286. int main(void)
  287. {
  288.     /* 전역변수로 사용하던 것을 메인에 선언 */
  289.     char emp_no[5][7]; /* 2차원 배열 선언 */
  290.     char name  [5][20];
  291.     char gender[5][10];
  292.     char jik   [5][20];
  293.     int j=0,m=0;
  294.    
  295.     /* 변수값 초기화, 메모리를 지정한 문자열로 채움: memset */
  296.     /* memset(채울메모리주소, 채울문자, 채울문자의개수) */
  297.     for(j=0; j<5; j++)
  298.     {
  299.         memset(emp_no[j],0x00,sizeof(emp_no[j])); /* NULL 값 초기화 */
  300.         memset(name[j],0x00,sizeof(name[j]));
  301.         memset(gender[j],0x00,sizeof(gender[j]));
  302.         memset(jik[j],0x00,sizeof(jik[j]));
  303.     }
  304.    
  305.     j=0; /* j값 = 열의 행번호를 증감시킬 변수 */
  306.     /* 함수 호출. 프로그램 시작 */
  307.     HowTo(); /* 프로그램 소개글 호출 */
  308.     Menu(&j, emp_no, name, gender, jik); /* j의 주소값을 참조함 : &j */
  309.     /* 2차원 배열은 상단에 선언으로 이미 주소값을 가짐. 변수명만 기입해도 무방 */
  310.     return 0;
  311. }


'C' 카테고리의 다른 글

c 표준 라이브러리 함수  (0) 2012.03.30
\n  (0) 2012.03.19