12 개의 재 미 있 는 C 언어 면접 문제

원본 주소:http://www.csdn.net/article/2012-09-06/2809604-12-c-interview-questions/1
1. gets () 함수
가: 다음 코드 에 있 는 질문 을 찾 아 보 세 요.

   
   
   
   
  1. #include<stdio.h> 
  2. int main(void
  3.     char buff[10]; 
  4.     memset(buff,0,sizeof(buff)); 
  5.  
  6.     gets(buff); 
  7.  
  8.     printf("
     The buffer entered is [%s]
    "
    ,buff); 
  9.  
  10.     return 0; 

답: 위 코드 의 문 제 는 함수 gets () 의 사용 입 니 다. 이 함 수 는 stdin 에서 복사 한 캐 시 용적 을 검사 하지 않 고 문자열 을 받 습 니 다. 캐 시 가 넘 칠 수 있 습 니 다.표준 함수 fgets () 로 대체 하 는 것 을 추천 합 니 다.
2. strcpy () 함수
Q. 다음은 간단 한 비밀번호 보호 기능 입 니 다. 비밀 번 호 를 모 르 고 풀 수 있 습 니까?

   
   
   
   
  1. #include<stdio.h> 
  2.  
  3. int main(int argc, char *argv[]) 
  4.     int flag = 0; 
  5.     char passwd[10]; 
  6.  
  7.     memset(passwd,0,sizeof(passwd)); 
  8.  
  9.     strcpy(passwd, argv[1]); 
  10.  
  11.     if(0 == strcmp("LinuxGeek", passwd)) 
  12.     { 
  13.         flag = 1; 
  14.     } 
  15.  
  16.     if(flag) 
  17.     { 
  18.         printf("
     Password cracked 
    "
    ); 
  19.     } 
  20.     else 
  21.     { 
  22.         printf("
     Incorrect passwd 
    "
    ); 
  23.  
  24.     } 
  25.     return 0; 

답: 상기 암호 화 를 푸 는 관건 은 strcpy () 함수 의 구멍 을 뚫 는 것 입 니 다.그래서 사용자 가 'passwd' 캐 시 에 무 작위 비밀 번 호 를 입력 할 때 'passwd' 의 용량 이 충분 한 지 미리 확인 하지 않 았 습 니 다.따라서 사용자 가 캐 시 넘 침 을 일 으 키 고 'flag' 변수 기본 값 이 존재 하 는 위치 에 있 는 메모리 의 긴 '비밀번호' 를 입력 하면 이 암호 가 검증 을 통과 하지 못 하 더 라 도 flag 인증 위치 가 0 이 아 닌 것 으로 바 뀌 면 보 호 된 데 이 터 를 얻 을 수 있 습 니 다.예 를 들 면:

   
   
   
   
  1. $ ./psswd aaaaaaaaaaaaa 
  2.  
  3. Password cracked 

위의 비밀 번 호 는 정확 하지 않 지만 캐 시 넘 침 을 통 해 비밀 번 호 를 안전하게 보호 할 수 있 습 니 다.
이러한 문 제 를 피 하려 면 strncpy () 함 수 를 사용 하 는 것 을 권장 합 니 다.
저 자 는 최근 컴 파일 러 가 내부 에서 스 택 이 넘 칠 가능성 을 감지 하기 때문에 스 택 에 변 수 를 저장 하면 스 택 이 넘 치기 어렵 습 니 다.내 gcc 에 서 는 기본적으로 이 렇 기 때문에 컴 파일 명령 인 '- fno - stack - protector' 를 사용 하여 이 방안 을 실현 해 야 합 니 다.
3. main () 의 반환 형식
가: 아래 코드 를 컴 파일 할 수 있 습 니까?만약 가능 하 다 면, 그것 은 어떤 잠재 적 인 문제 가 있 습 니까?

   
   
   
   
  1. #include<stdio.h> 
  2.  
  3. void main(void
  4.     char *ptr = (char*)malloc(10); 
  5.  
  6.     if(NULL == ptr) 
  7.     { 
  8.         printf("
     Malloc failed 
    "
    ); 
  9.         return
  10.     } 
  11.     else 
  12.     { 
  13.         // Do some processing 
  14.         free(ptr); 
  15.     } 
  16.  
  17.     return

답: main () 방법의 반환 형식 때문에 이 코드 의 오 류 는 대부분의 컴 파일 러 에서 경고 로 여 겨 집 니 다.main () 의 반환 유형 은 'int' 이지 'void' 가 아 닙 니 다."int" 반환 형식 은 프로그램 이 상태 값 을 되 돌려 주기 때 문 입 니 다.이 점 은 매우 중요 하 다. 특히 프로그램 이 성공 적 으로 실행 되 는 스 크 립 트 의 일부분 으로 실 행 될 때.
4. 메모리 유출
― 아래 코드 가 메모리 누 출 을 초래 할 수 있 습 니까?

   
   
   
   
  1. #include<stdio.h> 
  2.  
  3. void main(void
  4.     char *ptr = (char*)malloc(10); 
  5.  
  6.     if(NULL == ptr) 
  7.     { 
  8.         printf("
     Malloc failed 
    "
    ); 
  9.         return
  10.     } 
  11.     else 
  12.     { 
  13.         // Do some processing 
  14.     } 
  15.  
  16.     return

답: 위의 코드 가 "ptr" 에 분 배 된 메모 리 를 방출 하지 않 았 음 에 도 불구 하고 프로그램 이 종 료 된 후에 메모리 가 새 지 는 않 습 니 다.프로그램 이 끝 난 후에 이 프로그램 이 할당 한 메모리 가 자동 으로 처 리 됩 니 다.그러나 위의 코드 가 'while 순환' 에 있다 면 심각 한 메모리 누 출 문 제 를 초래 할 수 있 습 니 다!
알림: 메모리 누 출 에 대한 지식 과 메모리 누 출 검사 도 구 를 더 알 고 싶다 면 Valgrind 에 있 는 글 을 보 세 요.
5. free () 함수
― 다음 프로그램 은 사용자 가 'freeze' 를 입력 할 때 문제 가 발생 하지만 'zebra' 는 그렇지 않 습 니 다. 왜 요?

   
   
   
   
  1. #include<stdio.h> 
  2.  
  3. int main(int argc, char *argv[]) 
  4.     char *ptr = (char*)malloc(10); 
  5.  
  6.     if(NULL == ptr) 
  7.     { 
  8.         printf("
     Malloc failed 
    "
    ); 
  9.         return -1; 
  10.     } 
  11.     else if(argc == 1) 
  12.     { 
  13.         printf("
     Usage  
    "
    ); 
  14.     } 
  15.     else 
  16.     { 
  17.         memset(ptr, 0, 10); 
  18.  
  19.         strncpy(ptr, argv[1], 9); 
  20.  
  21.         while(*ptr != 'z'
  22.         { 
  23.             if(*ptr == ''
  24.                 break
  25.             else 
  26.                 ptr++; 
  27.         } 
  28.  
  29.         if(*ptr == 'z'
  30.         { 
  31.             printf("
     String contains 'z'
    "
    ); 
  32.             // Do some more processing 
  33.         } 
  34.  
  35.        free(ptr); 
  36.     } 
  37.  
  38.     return 0; 

답: 여기 서 문 제 는 코드 가 while 순환 에 저 장 된 주 소 를 수정 하 는 것 입 니 다."zebra" 를 입력 하면 while 순환 이 실행 되 기 전에 종료 되 므 로 free () 에 전 달 된 변 수 는 malloc () 에 전 달 된 주소 입 니 다.그러나 'freeze' 때 'ptr' 에 저 장 된 주 소 는 while 순환 에서 수정 되 기 때문에 free () 에 전 달 된 주소 가 잘못 되 어 seg - fault 나 붕 괴 를 초래 합 니 다.
6. 사용종료
― 아래 코드 에 서 는 atexit () 가 호출 되 지 않 았 습 니 다. 왜 요?

   
   
   
   
  1. #include<stdio.h> 
  2.  
  3. void func(void
  4.     printf("
     Cleanup function called 
    "
    ); 
  5.     return
  6.  
  7. int main(void
  8.     int i = 0; 
  9.  
  10.     atexit(func); 
  11.  
  12.     for(;i<0xffffff;i++); 
  13.  
  14.     _exit(0); 

이것 은exit () 함수 의 사용, 이 함 수 는 atexit () 등 함수 청 소 를 호출 하지 않 았 습 니 다.atexit () 를 사용 하면 exit () 또는 "return" 을 사용 해 야 합 니 다.
7. void * 와 C 구조 체
― 모든 종류의 인 자 를 받 아들 이 고 interger (정수) 결 과 를 되 돌려 줄 수 있 는 함 수 를 설계 할 수 있 습 니까?
답: 아래 와 같다.

  
  
  
  
  1. int func(void *ptr) 

만약 이 함수 의 매개 변수 가 하 나 를 초과 한다 면 이 함 수 는 하나의 구조 체 에서 호출 되 어야 합 니 다. 이 구조 체 는 전달 해 야 할 매개 변수 로 채 울 수 있 습 니 다.
8. * 와 + 작업
가: 다음 작업 은 무엇 을 출력 합 니까?왜?

  
  
  
  
  1. #include<stdio.h> 
  2.  
  3. int main(void
  4.     char *ptr = "Linux"
  5.     printf("
     [%c] 
    "
    ,*ptr++); 
  6.     printf("
     [%c] 
    "
    ,*ptr); 
  7.  
  8.     return 0; 

답: 출력 결 과 는 다음 과 같 아야 합 니 다:

  
  
  
  
  1. [L]  
  2.  
  3. [i] 

'+ +' 는 '*' 의 우선권 과 같 기 때문에 '* ptr + +' 는 '* (ptr + +)' 에 해당 한다.즉, ptr + + 를 먼저 실행 하고 그 다음 에 * ptr 를 실행 해 야 하기 때문에 조작 결 과 는 'L' 입 니 다.두 번 째 결 과 는 'i' 다.
9. 질문: 코드 세 션 수정 (또는 코드 만 읽 기)
가: 아래 코드 세그먼트 가 잘못 되 었 습 니 다. 지적 해 주 시 겠 습 니까?

  
  
  
  
  1. #include<stdio.h> 
  2.  
  3. int main(void
  4.     char *ptr = "Linux"
  5.     *ptr = 'T'
  6.  
  7.     printf("
     [%s] 
    "
    , ptr); 
  8.  
  9.     return 0; 

답: * ptr = 'T' 를 통 해 메모리 에 있 는 코드 세그먼트 (코드 만 읽 기) 'Linux' 의 첫 번 째 자모 가 바 뀌 기 때 문 입 니 다.이 조작 은 무효 이기 때문에 seg - fault 또는 붕 괴 를 초래 할 수 있 습 니 다.
10. 자신의 이름 을 바 꾸 는 프로 세 스
― 실행 중 프로 세 스 이름 을 바 꾸 는 프로그램 을 쓸 수 있 습 니까?
답: 아래 코드 참조:

  
  
  
  
  1. #include<stdio.h> 
  2.  
  3. int main(int argc, char *argv[]) 
  4.     int i = 0; 
  5.     char buff[100]; 
  6.  
  7.     memset(buff,0,sizeof(buff)); 
  8.  
  9.     strncpy(buff, argv[0], sizeof(buff)); 
  10.     memset(argv[0],0,strlen(buff)); 
  11.  
  12.     strncpy(argv[0], "NewName", 7); 
  13.  
  14.     // Simulate a wait. Check the process 
  15.     // name at this point. 
  16.     for(;i<0xffffffff;i++); 
  17.  
  18.     return 0; 

11. 로 컬 변수의 주 소 를 되 돌려 줍 니 다.
가: 다음 코드 에 문제 가 있 습 니까?있 으 면 어떻게 수정 해 야 합 니까?

  
  
  
  
  1. #include<stdio.h> 
  2.  
  3. int* inc(int val) 
  4.   int a = val; 
  5.   a++; 
  6.   return &a; 
  7.  
  8. int main(void
  9.     int a = 10; 
  10.     int *val = inc(a); 
  11.     printf("
     Incremented value is equal to [%d] 
    "
    , *val); 
  12.  
  13.     return 0; 

답: 위의 프로그램 이 가끔 정상적으로 실 행 될 수 있 지만 'inc ()' 에 심각 한 구멍 이 존재 합 니 다.이 함 수 는 로 컬 변수의 주 소 를 되 돌려 줍 니 다.로 컬 변수의 생명 주 기 는 'inc ()' 의 생명 주기 이기 때문에 inc 가 끝 난 후에 로 컬 변 수 를 사용 하면 좋 지 않 은 결과 가 발생 할 수 있 습 니 다.이것 은 main () 에서 변수 'a' 의 주 소 를 피 할 수 있 습 니 다. 그러면 나중에 이 주소 에 저 장 된 값 을 수정 할 수 있 습 니 다.
12. printf () 를 처리 하 는 인자
가: 다음 코드 는 무엇 을 출력 합 니까?

  
  
  
  
  1. #include<stdio.h> 
  2.  
  3. int main(void
  4.     int a = 10, b = 20, c = 30; 
  5.     printf("
     %d..%d..%d 
    "
    , a+b+c, (b = b*2), (c = c*2)); 
  6.  
  7.     return 0; 

답: 출력 결 과 는:

  
  
  
  
  1. 110..40..60 

이것 은 C 언어 에서 함수 의 매개 변 수 는 기본적으로 오른쪽 에서 왼쪽으로 처리 되 고 출력 할 때 왼쪽 에서 오른쪽으로 처리 되 기 때문이다.

좋은 웹페이지 즐겨찾기