C 프로그래머는 무엇을 알아야합니까? [닫은]


12

모든 괜찮은 C 프로그래머가 알아야 할 몇 가지 개념 / 기술 / 언어 기능은 무엇입니까 (일반적인 소프트웨어 엔지니어링 및 유사 사항은 제외하고 C 관련 항목에만 집중). 내 C 지식의 가능한 격차를 메울 수 있도록 알고 싶습니다.


9
Stack Overflow의 C 질문으로 시작하여 모르는 것이 있는지 확인하십시오.
chrisaycock

3
AC 프로그래머는 아마 알고 있어야합니다2 + 2 = 4
Edward Strange

21
방탄 신발을 판매하는 상점을 알아야합니다.
Adam Crossland

1
이 주제에 관한 수백 권의 책이 있습니다. 귀하의 질문은 매우 모호합니다. 당신은 단지 물건의 목록이 아닌 괜찮은 답변을 얻으려면 더 구체적이어야합니다. 그리고이 질문에서 지금까지 생성 된 답변을 보면서 나는 그것이 재 작업 또는 폐쇄되어야한다고 생각합니다.
Walter

2
다른 프로그래밍 언어?
무하마드 알카로 우리

답변:


19

C에만 해당됩니까? 대부분의 절차 언어에 공통적 인 표준 구성 외에도 다음과 같이 말해야합니다.

  • (ab) 전 처리기 사용
  • 링커 대 컴파일러
  • 포인터 포인터 포인터!
  • 배열이 포인터 인 배열
  • C 문자열의 작동 방식 및 포인터 및 배열의 ​​방법
  • C 문자열 사용으로 인해 버퍼 오버플로 가 발생할 수있는 정도
  • 무엇이든 캐스팅하는 법 (결국 1과 0) :)
  • 수동 메모리 관리 malloc / free
  • 스택 대 힙
  • 포인터 앨리어싱 (C99에서 불법 인 이유)
  • 엄격하게 클래스 대신 공개적으로 노출 된 함수 세트를 사용하여 모듈 (.h / .c 파일) 측면에서 개발에 대한 생각
  • 노동 조합
  • Sprintf가 발을 날려 버릴 수있는 이유
  • 함수 포인터

"버퍼 오버 플로우"를 목록에 추가합니다.
Aidan Cully

@ 아이 단, 잘 잡아. 추가되었습니다.
Doug T.

2
C 배열과 포인터가 동일하지 않은 방법 : books.google.ca/…
Matthieu

포인터는 적어도 3 배 이상 반복되어야합니다
Gaurav

8

포인터를 이해하면 컴퓨터를 이해할 수 있습니다.


12
아니, 당신은 단순히 컴퓨터를 이해한다는 착각을 얻게 될 것입니다.
직업

5

피타 그라의 탁월한 답변 외에도

다음과 같은 복잡한 선언을 작성 (또는 적어도 읽음)하는 방법 char (*(*funcs[4])())[10]

funcs는 char의 array [10]에 대한 포인터를 반환하는 함수에 대한 포인터의 배열 [4]입니다.


1
너무 복잡해지면 아마도 주석에 속합니까?
직업

7
어쩌면 그는 그런 글을 피하는 법을 배워야할까요?
FabianB

3
  1. 정수 승격 규칙
  2. 모든 것을 알려진 값으로 초기화
  3. GOTO는 특히 예외 / 실패 처리에 사용될 때 악하지 않습니다
  4. malloc 및 / 또는 calloc은 NULL을 반환 할 수 있습니다 ... 체크 반환 값을 확인하십시오
  5. 작은 메모리 할당이 자주 발생하면 힙에서 조각화가 발생할 수 있습니다.
  6. 포인터 산술
  7. 비트 마스크는 당신의 친구입니다
  8. 부호없는 정수의 경우 x >> 1은 x / 2와 같습니다.

GOTO 악의에 대 한 +1 :)
zvrba

2

AC 프로그래머는 다른 언어를 알아야합니다! ;-) OOP, 함수형 프로그래밍 등과 같은 다양한 패러다임의 다른 언어의 개념을 아는 것이 항상 유익합니다.

더 진지하게, 난독 화 된 프로그래밍 콘테스트를 보는 것은 재미 있고 흥미롭게도 좋은 경험이기도합니다.


2

피타 그라스의 답변에 대한 언급에서 "버퍼 오버플로"를 언급했는데 아마도 내가 의미하는 바를 분명히해야 할 것입니다. C에서는 알고 충분하지 않습니다 것을 메모리로 직접 작업하는 것은 위험하다 - 당신은 또한 위험있는 정확한 방법을 이해해야합니다. 나는이 모든 경우에 대해 "발로 자신을 찍는"은유를 좋아하지 않습니다. 많은 시간 동안, 그것은 당신 이 방아쇠 당기는 것이 아니라 종종 당신이나 당신의 사용자에 반하는 관심을 가진 배우입니다. .

당신이 함수를 호출 할 때, 함수의 반환 주소가 스택에 배치됩니다 - 예를 들어, 내림차순 스택과 아키텍처 (x86 및 ARM 일반적으로 포함 된 가장 인기있는 아키텍처는이 법안에 맞게) 이후 에 정의 로컬 변수를 기능의 본문. 따라서 버퍼를 로컬 변수로 선언하고 버퍼 오버플로를 확인하지 않고 해당 변수를 외부 세계에 노출하면 다음과 같이됩니다.

void myFn(void) {
    char buf[256];
    gets(buf);
}

외부 사용자는 스택에서 반환 주소를 덮어 쓰는 문자열을 보낼 수 있습니다. 기본적으로 현재 함수로 이어지는 호출 그래프에 대한 프로그램의 런타임 아이디어를 변경할 수 있습니다. 따라서 사용자는 아키텍처에 대한 일부 실행 코드의 이진 표현, 스택에서 오버플로하기에 충분한 패딩 myFn및 반환 주소를 덮어 쓸 수있는 추가 데이터를 제공하는 문자열을 myFn제공합니다. 이러한 상황이 발생하면 myFn일반적으로 호출자에게 제어권을 반환 했을 때 악의적 인 사용자가 제공 한 코드로 분기됩니다. 신뢰할 수없는 사용자에게 노출 될 가능성이있는 C (또는 C ++) 코드 를 작성하는 경우이 공격 경로를 이해해야합니다.. 스택에 대한 버퍼 오버플로가 힙에 대한 버퍼 오버플로보다 종종 (항상 그런 것은 아님) 종종 더 쉽게 이용 가능한 이유를 이해해야하며 힙의 메모리가 어떻게 배치되는지 이해해야합니다. • 그래도 아이디어 malloc()'에드 영역은 프로그램이 다른에서 충돌 왜 이해하는 데 도움이 주변의 제어 구조가 malloc(), 나에를 free()).

C는 머신 작동 방식에 대한 상세 정보를 제공하며 오늘날 널리 사용되는 다른 사용자 편집 언어보다 머신을 직접 제어합니다. 강력한 힘을 발휘하면 큰 책임이 따릅니다. 실제로 C와 안전하고 효과적으로 작업하려면 이러한 하위 수준의 세부 사항을 이해해야합니다.


0

다른 좋은 답변 외에도 방어 프로그래밍 기술을 목록 에 추가하고 싶습니다 .

예를 들어 기능을 시작 / 종료 할 때 어설 션을 사용하여 계약을 확인합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.