12 개의 재 미 있 는 C 언어 면접 문제
1. gets () 함수
가: 다음 코드 에 있 는 질문 을 찾 아 보 세 요.
- #include<stdio.h>
- int main(void)
- {
- char buff[10];
- memset(buff,0,sizeof(buff));
-
- gets(buff);
-
- printf("
The buffer entered is [%s]
",buff);
-
- return 0;
- }
답: 위 코드 의 문 제 는 함수 gets () 의 사용 입 니 다. 이 함 수 는 stdin 에서 복사 한 캐 시 용적 을 검사 하지 않 고 문자열 을 받 습 니 다. 캐 시 가 넘 칠 수 있 습 니 다.표준 함수 fgets () 로 대체 하 는 것 을 추천 합 니 다.
2. strcpy () 함수
Q. 다음은 간단 한 비밀번호 보호 기능 입 니 다. 비밀 번 호 를 모 르 고 풀 수 있 습 니까?
- #include<stdio.h>
-
- int main(int argc, char *argv[])
- {
- int flag = 0;
- char passwd[10];
-
- memset(passwd,0,sizeof(passwd));
-
- strcpy(passwd, argv[1]);
-
- if(0 == strcmp("LinuxGeek", passwd))
- {
- flag = 1;
- }
-
- if(flag)
- {
- printf("
Password cracked
");
- }
- else
- {
- printf("
Incorrect passwd
");
-
- }
- return 0;
- }
답: 상기 암호 화 를 푸 는 관건 은 strcpy () 함수 의 구멍 을 뚫 는 것 입 니 다.그래서 사용자 가 'passwd' 캐 시 에 무 작위 비밀 번 호 를 입력 할 때 'passwd' 의 용량 이 충분 한 지 미리 확인 하지 않 았 습 니 다.따라서 사용자 가 캐 시 넘 침 을 일 으 키 고 'flag' 변수 기본 값 이 존재 하 는 위치 에 있 는 메모리 의 긴 '비밀번호' 를 입력 하면 이 암호 가 검증 을 통과 하지 못 하 더 라 도 flag 인증 위치 가 0 이 아 닌 것 으로 바 뀌 면 보 호 된 데 이 터 를 얻 을 수 있 습 니 다.예 를 들 면:
- $ ./psswd aaaaaaaaaaaaa
-
- Password cracked
위의 비밀 번 호 는 정확 하지 않 지만 캐 시 넘 침 을 통 해 비밀 번 호 를 안전하게 보호 할 수 있 습 니 다.
이러한 문 제 를 피 하려 면 strncpy () 함 수 를 사용 하 는 것 을 권장 합 니 다.
저 자 는 최근 컴 파일 러 가 내부 에서 스 택 이 넘 칠 가능성 을 감지 하기 때문에 스 택 에 변 수 를 저장 하면 스 택 이 넘 치기 어렵 습 니 다.내 gcc 에 서 는 기본적으로 이 렇 기 때문에 컴 파일 명령 인 '- fno - stack - protector' 를 사용 하여 이 방안 을 실현 해 야 합 니 다.
3. main () 의 반환 형식
가: 아래 코드 를 컴 파일 할 수 있 습 니까?만약 가능 하 다 면, 그것 은 어떤 잠재 적 인 문제 가 있 습 니까?
- #include<stdio.h>
-
- void main(void)
- {
- char *ptr = (char*)malloc(10);
-
- if(NULL == ptr)
- {
- printf("
Malloc failed
");
- return;
- }
- else
- {
- // Do some processing
- free(ptr);
- }
-
- return;
- }
답: main () 방법의 반환 형식 때문에 이 코드 의 오 류 는 대부분의 컴 파일 러 에서 경고 로 여 겨 집 니 다.main () 의 반환 유형 은 'int' 이지 'void' 가 아 닙 니 다."int" 반환 형식 은 프로그램 이 상태 값 을 되 돌려 주기 때 문 입 니 다.이 점 은 매우 중요 하 다. 특히 프로그램 이 성공 적 으로 실행 되 는 스 크 립 트 의 일부분 으로 실 행 될 때.
4. 메모리 유출
― 아래 코드 가 메모리 누 출 을 초래 할 수 있 습 니까?
- #include<stdio.h>
-
- void main(void)
- {
- char *ptr = (char*)malloc(10);
-
- if(NULL == ptr)
- {
- printf("
Malloc failed
");
- return;
- }
- else
- {
- // Do some processing
- }
-
- return;
- }
답: 위의 코드 가 "ptr" 에 분 배 된 메모 리 를 방출 하지 않 았 음 에 도 불구 하고 프로그램 이 종 료 된 후에 메모리 가 새 지 는 않 습 니 다.프로그램 이 끝 난 후에 이 프로그램 이 할당 한 메모리 가 자동 으로 처 리 됩 니 다.그러나 위의 코드 가 'while 순환' 에 있다 면 심각 한 메모리 누 출 문 제 를 초래 할 수 있 습 니 다!
알림: 메모리 누 출 에 대한 지식 과 메모리 누 출 검사 도 구 를 더 알 고 싶다 면 Valgrind 에 있 는 글 을 보 세 요.
5. free () 함수
― 다음 프로그램 은 사용자 가 'freeze' 를 입력 할 때 문제 가 발생 하지만 'zebra' 는 그렇지 않 습 니 다. 왜 요?
- #include<stdio.h>
-
- int main(int argc, char *argv[])
- {
- char *ptr = (char*)malloc(10);
-
- if(NULL == ptr)
- {
- printf("
Malloc failed
");
- return -1;
- }
- else if(argc == 1)
- {
- printf("
Usage
");
- }
- else
- {
- memset(ptr, 0, 10);
-
- strncpy(ptr, argv[1], 9);
-
- while(*ptr != 'z')
- {
- if(*ptr == '')
- break;
- else
- ptr++;
- }
-
- if(*ptr == 'z')
- {
- printf("
String contains 'z'
");
- // Do some more processing
- }
-
- free(ptr);
- }
-
- return 0;
- }
답: 여기 서 문 제 는 코드 가 while 순환 에 저 장 된 주 소 를 수정 하 는 것 입 니 다."zebra" 를 입력 하면 while 순환 이 실행 되 기 전에 종료 되 므 로 free () 에 전 달 된 변 수 는 malloc () 에 전 달 된 주소 입 니 다.그러나 'freeze' 때 'ptr' 에 저 장 된 주 소 는 while 순환 에서 수정 되 기 때문에 free () 에 전 달 된 주소 가 잘못 되 어 seg - fault 나 붕 괴 를 초래 합 니 다.
6. 사용종료
― 아래 코드 에 서 는 atexit () 가 호출 되 지 않 았 습 니 다. 왜 요?
- #include<stdio.h>
-
- void func(void)
- {
- printf("
Cleanup function called
");
- return;
- }
-
- int main(void)
- {
- int i = 0;
-
- atexit(func);
-
- for(;i<0xffffff;i++);
-
- _exit(0);
- }
이것 은exit () 함수 의 사용, 이 함 수 는 atexit () 등 함수 청 소 를 호출 하지 않 았 습 니 다.atexit () 를 사용 하면 exit () 또는 "return" 을 사용 해 야 합 니 다.
7. void * 와 C 구조 체
― 모든 종류의 인 자 를 받 아들 이 고 interger (정수) 결 과 를 되 돌려 줄 수 있 는 함 수 를 설계 할 수 있 습 니까?
답: 아래 와 같다.
- int func(void *ptr)
만약 이 함수 의 매개 변수 가 하 나 를 초과 한다 면 이 함 수 는 하나의 구조 체 에서 호출 되 어야 합 니 다. 이 구조 체 는 전달 해 야 할 매개 변수 로 채 울 수 있 습 니 다.
8. * 와 + 작업
가: 다음 작업 은 무엇 을 출력 합 니까?왜?
- #include<stdio.h>
-
- int main(void)
- {
- char *ptr = "Linux";
- printf("
[%c]
",*ptr++);
- printf("
[%c]
",*ptr);
-
- return 0;
- }
답: 출력 결 과 는 다음 과 같 아야 합 니 다:
- [L]
-
- [i]
'+ +' 는 '*' 의 우선권 과 같 기 때문에 '* ptr + +' 는 '* (ptr + +)' 에 해당 한다.즉, ptr + + 를 먼저 실행 하고 그 다음 에 * ptr 를 실행 해 야 하기 때문에 조작 결 과 는 'L' 입 니 다.두 번 째 결 과 는 'i' 다.
9. 질문: 코드 세 션 수정 (또는 코드 만 읽 기)
가: 아래 코드 세그먼트 가 잘못 되 었 습 니 다. 지적 해 주 시 겠 습 니까?
- #include<stdio.h>
-
- int main(void)
- {
- char *ptr = "Linux";
- *ptr = 'T';
-
- printf("
[%s]
", ptr);
-
- return 0;
- }
답: * ptr = 'T' 를 통 해 메모리 에 있 는 코드 세그먼트 (코드 만 읽 기) 'Linux' 의 첫 번 째 자모 가 바 뀌 기 때 문 입 니 다.이 조작 은 무효 이기 때문에 seg - fault 또는 붕 괴 를 초래 할 수 있 습 니 다.
10. 자신의 이름 을 바 꾸 는 프로 세 스
― 실행 중 프로 세 스 이름 을 바 꾸 는 프로그램 을 쓸 수 있 습 니까?
답: 아래 코드 참조:
- #include<stdio.h>
-
- int main(int argc, char *argv[])
- {
- int i = 0;
- char buff[100];
-
- memset(buff,0,sizeof(buff));
-
- strncpy(buff, argv[0], sizeof(buff));
- memset(argv[0],0,strlen(buff));
-
- strncpy(argv[0], "NewName", 7);
-
- // Simulate a wait. Check the process
- // name at this point.
- for(;i<0xffffffff;i++);
-
- return 0;
- }
11. 로 컬 변수의 주 소 를 되 돌려 줍 니 다.
가: 다음 코드 에 문제 가 있 습 니까?있 으 면 어떻게 수정 해 야 합 니까?
- #include<stdio.h>
-
- int* inc(int val)
- {
- int a = val;
- a++;
- return &a;
- }
-
- int main(void)
- {
- int a = 10;
- int *val = inc(a);
- printf("
Incremented value is equal to [%d]
", *val);
-
- return 0;
- }
답: 위의 프로그램 이 가끔 정상적으로 실 행 될 수 있 지만 'inc ()' 에 심각 한 구멍 이 존재 합 니 다.이 함 수 는 로 컬 변수의 주 소 를 되 돌려 줍 니 다.로 컬 변수의 생명 주 기 는 'inc ()' 의 생명 주기 이기 때문에 inc 가 끝 난 후에 로 컬 변 수 를 사용 하면 좋 지 않 은 결과 가 발생 할 수 있 습 니 다.이것 은 main () 에서 변수 'a' 의 주 소 를 피 할 수 있 습 니 다. 그러면 나중에 이 주소 에 저 장 된 값 을 수정 할 수 있 습 니 다.
12. printf () 를 처리 하 는 인자
가: 다음 코드 는 무엇 을 출력 합 니까?
- #include<stdio.h>
-
- int main(void)
- {
- int a = 10, b = 20, c = 30;
- printf("
%d..%d..%d
", a+b+c, (b = b*2), (c = c*2));
-
- return 0;
- }
답: 출력 결 과 는:
- 110..40..60
이것 은 C 언어 에서 함수 의 매개 변 수 는 기본적으로 오른쪽 에서 왼쪽으로 처리 되 고 출력 할 때 왼쪽 에서 오른쪽으로 처리 되 기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.