>> Delete Reply from No. 11929 article
No. RE: 도움이 될진 모르겠지만.. 참고 ^^

등록 2000-11-19 14:10:00 By localhost     조회 2
이름 liberta    

		/***
먼저, 어떤 책을 보고 계신 건지는 모르겠지만 아마 유닉스 시스템에서 '환경변수'
라고 부르는 값들에 대한 부분 같군요.  서브루틴의 이름을 ourgetenv()로 했다는
것은 getenv()라는 것이 실제로 있기 때문에 혼동되지 않도록 하는 거겠죠?
 $ man getenv
  [리턴값 부분]
매뉴얼 페이지의 내용을 보니 - 다른 부분 필요없고 "return" 부분만 봅시다! -
이 함수는 파라미터로 넘겨받은 문자열과 매칭되는 것이 있는지 유닉스 시스템의
환경변수들 중에서 찾아보고, 있다면 해당하는 환경변수에 대한 포인터를, 없다면
NULL을 리턴한다고 되어 있군요.  그럼 다음 두 라인에 대한 의문은 해결됩니다.
 if(있다면) return ((char *) & (tmp[length+1]));
==> 이 라인은 for루프 내부에 있군요. 결론부터 말씀드리자면 if(있다면) 이 조건은
ourgetenv() 함수가 넘겨받은 파라미터 char *envName 이 유닉스 환경변수들 중
하나와 일치한다면 '참'이 되게끔 되어 있습니다. 예를들어 ourgetenv("HOME") 이런
건 대부분의 시스템에서 '참'이 될 겁니다.
근데 리턴이 왜 (char *) & (tmp[length+1])) 이렇게 되어야 되는 걸까요. 이건
잠시 후에... 일단 조건이 '참'이라면 리턴은 환경변수의 값에 대한 포인터가 됩니다.
예를들어 ourgetenv("HOME")의 리턴값은 문자열 "/home/liberta"에 대한 포인터.
 (없다면) return ((char *)0);
==> 여기서 '0'은 차라리 NULL이라고 했어야 좋을텐데.
어쨌든 NULL을 타입캐스팅해서 (char *)로 리턴했으므로 이 돌려받은 리턴값으로
뭘 할 수 있을까요?  이 리턴값을 읽으면 바로 NULL 문자 자체, 즉 문자열의 첫
머리에 NULL이 있다는 건 비어있는 문자열이죠.  "" 이런 거..
  [환경변수에 대해]
유닉스 시스템의 환경변수에 액세스하려면 extern char **environ; 이라고 사용자의
프로그램에서 호출해 주면 되고, 실제로 environ 이라는 2차원 배열은 <unistd.h>에
구현되어 있다고 나와 있군요. ($ man environ)  또한 이 2차원 배열은 생긴 모양이
이렇다고 되어 있습니다. (예를들어...)
char **environ={
  "USER=liberta",           // 문자열이 1차원이니깐 문자열 배열은 2차원 배열,
  "LOGNAME=liberta",        // 또한 2차원 배열에 대한 포인터는 당근 2차원(**)!
  "HOME=/home/liberta",     // char *env 는 char **env 와 "차원"이 다릅니다.
  "SHELL=/bin/bash"         // "변수=변수의값" 이런 모양, 중간에 '=' 주의!
}
 예를들어 ourgetenv() 에 "HOME"이라는 파라미터를 줘서 호출했다고 합시다. 그리고
차례대로 소스를 따라갑니다.
 extern char **environ;  // 보아하니 *environ[0]는 "USER=liberta", 이런 식이죠?
                        // 2차원 포인터임에 주의...
 char *ourgetenv (const char *envName)  // envName="HOME", 이렇게 가정 하자구요.
{
const char *tmp;    // 이건 environ에서 원소(문자열)를 한 줄씩 끌어내기 위해..
size_t length;      // size_t는 아마 stdio.h에 있을 겁니다. 아니면 근처(?)에..
 length = strlen(envName);  // 이 경우엔 strlen("HOME"), 당근 4가 됩니다.
 // for루프 : tmp 포인터에 environ 원소들을 차례대로 하나씩 넣습니다.
// tmp = *environ : tmp는 environ의 첫번째 문자열에 대한 포인터로 초기화.
// '' != *tmp : 이 조건에 의해 tmp는 environ의 "모든" 원소를 탐색하게 됩니다.
// tmp+=strlen(tmp) :
 tmp = "USER=liberta", 이 경우 strlen(tmp)는 12, 그러므로
//                 tmp+=strlen(tmp)에 의해 
tmp가 가리키게 될 주소는 두번째
//                 문자열("LOGNAME=liberta")의 주소. tmp는 
이런 식으로 변화...
for (tmp = *environ; '' != *tmp; tmp += strlen(tmp)){
 // if조건문 : 함수의 파라미
터(envName)와 tmp가 가리키는 문자열들을 비교 합니다.
// strncmp() : 이 경우, 우선 tmp에 "HOME"이
 포함되는지 먼저 조사합니다.
// '=' == tmp[length] : 그리고 반드시 "HOME=" 까지 확인해야 하겠
죠, '=' 확인.
  if (!(strncmp(tmp,envName,length)) && ('=' == tmp[length]))
 // 매치되는 tmp 문자열에서, 
먼저 tmp[length+1]을 찾습니다. "HOME=/home/liberta"
// 에서 리턴값은 "/home/liberta"가 되면 되는 거
니깐. tmp[length]가 '='였죠?
// 이렇게 찾은 문자열 "/home/liberta"를 그냥 (char *)tmp[length+1] 이라
고
// 리턴하지 않고 & 이런 걸 해주는 건 글쎄요... 아마 선언만 하고 값이
// 지정되지 않은
 환경변수들, 예를들어 "HOME=" 이렇게만 되어있는 경우에 대해
// 체크해서, 이 경우 적당히 
NULL을 곧바로 리턴하고 빠져나와 버리기 위한 것
// 같은데... 어떻게 되나 실험해 보세요! ^
^ (언어공부는 수많은 실험과 삽질로!)
    return ((char *) & (tmp[length+1]));
}
return ((char *)0);
}
 -
-
나는 그녀의 배경에 쫄지도 않고 그녀의 철없음을 나무라지도 않고... 오직
사랑의 대상
으로만 생각하고 싶다.  그러나 언제나 나를 재어보고 있는 그녀의
메마른 눈빛은 나를 힘
들게 한다.                                  <친구넘의 말..>
[관리자] 패스워드를 입력 하십시오. 답장이 존재하면 함께 삭제됩니다.[ 목록 | 이전 ]
패스워드:    

Copyleft 1999-2026 by JSBoard Open Project
Theme Designed by IDOO All right reserved