고급 언어로는 배울 수없는 C로부터 어떤 원칙을 배울 수 있습니까? [닫은]


11

나는 C가 프로그래밍의 원리를 배우기에 좋은 언어라고 생각합니다. 루비와 같은 고급 언어에서 "매직 된"저급 언어로 무엇을 배울 수 있습니까?


2
어쨌든 magick 또는 그중 일부를 배웁니다. C는 "금속에 더 가깝기 때문에"금속에 대해 더 많이 배웁니다.
Robert Harvey

1
C ++을 만날 때까지 참조 개념을 완전히 이해하지 못했습니다.
user6245072

6
C는 실제로 스택 오버플로가 무엇인지 알려줍니다. 어려운 방법.
david25272

1
저는 새로운 프로그래머가 좋은 파스칼과 구조화 된 프로그래밍을 배우는 것으로 시작하기를 바랍니다. 자신을 논리적이고 체계적으로 표현하는 법을 배웁니다.
벤트

2
C와 C ++만이 가르쳐주는 것은 컴파일러가 최악의 적이라는 것입니다.
코드 InChaos

답변:


9

컴퓨터 과학의 일반적인 추상 의미에서 C에는 존재하지만 고급 언어에는 존재하지 않는 원칙은 없습니다. 모든 컴퓨터 과학은 알고리즘으로 요약되며 모든 알고리즘은 C와 같이 Turing-complete 인 모든 언어로 구현 될 수 있습니다.

C가 더 높은 수준의 언어에서 나눠지는 차이점은 기계어 코드가 C와 차이가 나는 차이점과 비슷합니다. 기계와 코드의 관계.

고급 언어로 코드를 작성할 때 코드가 기계와 상호 작용하는 방식에 (일반적으로) 신경 쓰지 않아도됩니다. 언어가 자체적으로 정의한 가상 머신은 코드 실행의 여러 측면을 숨 깁니다.

C에서는 프로그램과 메모리의 상호 작용이 최전선에서 유지됩니다. 단순히 힙 사용을 관리해야하는 것 이상이며, 코드와 스택의 상호 작용, 코드의 단순한 메모리 액세스 가 코드의 동작 및 성능에 미치는 영향, 메모리 액세스 순서조차 포함하지 않습니다. 잘못된 시간에 잘못된 메모리를 읽으면 성능이 효과적으로 저하 될 수 있으므로주의를 피할 수 있습니다.

높은 수준의 언어에서 이러한 것들은 분명하지 않습니다. 메모리는 사용자 모르게, 때로는 프롬프트없이 할당 및 할당 해제됩니다. 대부분의 경우 이것은 단순히 통제 할 수없는 것입니다. 대부분의 메모리 할당시기, 장소, 방법 및 이유는 단순히 숨겨져 있습니다.

마찬가지로 기계 코드 또는 어셈블리 코드를 작성하면 포 그라운드에 더 많은 세부 정보가 표시됩니다. 거의 외부에 거의 아무것도 남지 않으며 코드는 모든 할당, 모든 리소스, 전달되는 모든 데이터를 인식해야합니다. CPU의 레지스터를 통해-고급 언어에서 제거 된 지식.


6
나는 사람들이 왜 이런 종류의 토론에서 튜링 완전성을 언급하는지 이해하지 못했습니다. 튜링-완전성은이 맥락에서 의미가 없습니다. C는 그런 점에서 다른 프로그래밍 언어와 다르지 않으므로 C로 전환하여 Turing-completeness에 대해 배울 점은 없습니다. Turing-completeness가 관련이되는 유일한 시간은 CSS 또는 HTML과 같이 Turing-complete 가 아닌 것을 논의 할 때입니다. . 지옥, 당신이 충분히 찡그린 경우 에도 튜링 완료 입니다. 보다 의미있는 질문은 사용성에
Robert Harvey

3
@RobertHarvey 저의 요점은 언어가 합리적인 최소의 계산 능력을 가지고있는 한, "수준"은 알고리즘의 관점에서 무의미하다는 것입니다.이 맥락에서 중요한 것은 이것뿐입니다.
greyfade

3
OP의 질문과는 완전히 다른 점을 지적하고 있기 때문입니다. 프로그래머는 항상이 작업을 수행합니다. 실제 용어에서 의미있는 의미를 갖는 것처럼 "Turing-complete"라는 문구를 사용합니다. 중요하지 않다는 것을 제외하고 는 중요하지 않습니다.
Robert Harvey

2
<irony> 생물학은 입자 화학의 특별한 경우 인 화학의 특별한 경우입니다. 입자 물리학을 알고 있다면 생물학에서 배울 수있는 것은 없습니다. 맞습니까? </ irony>
Florian F

3
C는 단순히 할당 및 할당 해제를 명시 적으로 요구하지만 "높은 수준의"언어와 마찬가지로 여전히 추상적 인 시스템과 관련이 있습니다. 물리적 (예 : x86 시스템)은 여전히 ​​C의 범위를 벗어납니다. C 코드를 해석하지만 물리적 시스템의 메모리 할당을 제어 할 수없는 완벽한 샌드 박스 VM을 만들 수 있으며 여전히 100 % 호환 구현 일 수 있습니다.
Theodoros Chatzigiannakis

13

나는 C가 프로그래밍의 원리를 배우기에 좋은 언어라는 것을 알고 있습니다.

동의하지 않습니다. C에는 프로그래밍의 원리를 배우기에는 너무 많은 기능이 없습니다. 추상화를 생성하는 C의 기능은 끔찍하며 추상화는 프로그래밍의 핵심 원칙 중 하나입니다.

하드웨어의 작동 방식과 머신에 대한 기계적인 동정을 배우려면 명령어 세트 아키텍처라고하는 머신 코드를 배우고 최신 CPU의 캐시 구성을 연구해야합니다. 어셈블리 언어를 권장하지 않고 하드웨어 명령어 만 이해하면 컴파일러에서 생성하는 내용을 이해할 수 있습니다.

프로그래밍 원리를 배우려면 Java, C # 또는 Swift와 같은 현대 언어 또는 Rust와 같은 수십 가지 언어 중 하나를 사용하십시오. 또한 기능을 포함한 다양한 종류의 프로그래밍 패러다임을 연구하십시오.


12
C는 추상화를 만드는 데 능숙합니다. 당신은 C의 방법을 쓸 수 있습니다, 당신은 C. 무엇 C를 사용하여 개발 된 C. 전체 운영 체제의 구조로 데이터를 패키징 할 수 없는 객체 지향이 무엇의 모든 사람의 "현대"아이디어 만족입니다 잘 되어 보기로를 처럼.
Robert Harvey

4
좀 빠지는. C는 ASM보다 약간 높은 수준입니다. 하지만 그냥, 그 안에 클래스를 사용하는 기대하지 않는다 그렇게 할 수있는 방법이 있습니다 당신이 그렇게 경사하는 경우가.
Robert Harvey

4
귀하의 의견에 "assembler"대신 "Brainfuck"을 사용하십시오. 그렇다고해서 곧 Brainfuck을 사용한다는 의미는 아닙니다.
Robert Harvey

6
C의 기능에 대한 당신의 주장은 클래스 (및 가비지 수집 등)가 새로운 프로그래머 (필자가 아닌)를 가르치는 데 필요한 요소라고 믿는 경우에만 가치가 있습니다. 여기서 아무도 클래스없는 언어로 클래스를 사용하려고한다고 주장하는 사람은 없습니다.
Robert Harvey

5
@Robert, 내 주장은 C가 저급 언어이며, 따라서 프로그래밍 원리를 이해하는 데 가장 적합한 언어는 아니며 어셈블러에 대해서도 말할 수 있으며, 저급 언어라는 의미는 아닙니다. 그것들은 어떻게 든 "진정한"프로그래밍 원칙에 더 가깝습니다. 이러한 언어는 하드웨어와 운영 체제의 작동 방식을 이해하는 것이 더 좋으며, 관심이있는 경우 명령 세트 아키텍처 및 기계 언어를 학습하는 데있어 가장 낮은 수준으로 건너 뛰는 것이 좋습니다. 그렇지 않으면 선택할 수있는 언어가 많이 있습니다.
Erik Eidt

8

C와 (추상적 인) 기계

대부분의 프로그래밍 언어는 추상 기계로 설명됩니다. 그런 다음 컴파일러, 링커, 어셈블러, 인터프리터, 정적 분석기, 중간 언어 및 하드웨어와 같은 도구 세트를 사용하여 구현됩니다.이 도구 는 프로그램에서 관찰 한 것처럼 최소한 추상 기계의 예상되는 모든 동작을 존중하는 결과를 종합적으로 생성합니다. .

C는 위 규칙의 예외가 아닙니다. 실제 하드웨어에 대한 개념이없는 추상 시스템으로 설명됩니다.

따라서 사람들이 C가 컴퓨터의 실제 작동 방식을 가르쳐 준다고 말할 때 일반적으로 C는 C의 작동 방식을 가르쳐줍니다. 그러나 C는 시스템 프로그래밍에 널리 퍼져 있기 때문에 많은 사람들이 컴퓨터 자체와 혼동하기 시작합니다. 저는 개인적으로 컴퓨터 자체의 작동 방식을 아는 것보다 C의 작동 방식을 아는 것이 더 중요하다고 말합니다.

그러나 여전히 C와 컴퓨터 다릅니다. 실제 하드웨어는 실제로 C 사양을 아동용 책처럼 읽게하는 방식으로 복잡합니다. 하드웨어 작동 방식에 관심이 있으시면 언제든지 설명서를 찾아 어셈블러에서 코드 작성을 시작할 수 있습니다. 또는 언제든지 디지털 회로에 대해 배우기 시작하여 직접 하드웨어를 설계 할 수 있습니다. (최소한, 당신은 높은 수준의 C가 얼마나 좋은지 알게 될 것입니다.)

어떻게 합니까 당신은입니까? 그리고 어떻게 당신은 입니까?

실제로 하드웨어에 대해 배우는 것은 C 이외의 것을 포함하지만 C는 오늘날 프로그래머에게 다른 것을 가르 칠 수 있습니까?

나는 그것이 달려 있다고 생각합니다.

  • 개념 을 제안하고 권장하는 환경에서 여러 가지 방법으로 일 함으로써 개념 더 잘 배울 수 있다고 말하는 사람들이 있습니다 .
  • 개념 을 제공하지 않는 환경에서 작업하고 대신 직접 개념을 구축해야하는 곳에서 개념 더 잘 배울 수 있다고 말하는 사람들이 있습니다 .

이러한 가능성 중 하나를 너무 빨리 선택하지 마십시오. 나는 몇 년 동안 코드를 작성해 왔지만 어느 것이 정답인지, 정답이 둘 중 하나인지, 또는이 문제에 대한 정답과 같은 것이 있는지 전혀 모른다.

나는 당신이 아마 두 가지 옵션을 모두 내가 설명한 순서대로 느슨하게 적용해야한다고 생각하는 경향이 있습니다. 그러나 이것이 실제로 기술적 인 문제라고 생각하지 않습니다. 나는 그것이 대부분 교육적인 것이라고 생각합니다. 모든 사람은 크게 다른 방식으로 배우는 것 같습니다.

C에서만

적어도 내가 제안한 두 번째 옵션을 포함하여 위의 질문에 대답했다면, 당신은 이미 당신의 벨트 아래에 몇 가지 답변을 가지고 있습니다 : 더 높은 수준의 언어로 배울 수있는 것은 C 나에서 다시 발명함으로써 더 잘 배울 수 있습니다 믹스에 C를 첨가하여 최소 팽창.

그러나 대답에 관계없이 C (및 소수의 다른 언어)에서 거의 독점적으로 배울 수있는 몇 가지 사항이 있습니다.

  • C는 역사적으로 중요합니다. 그것은 우리가 어디에서 왔는지보고 감사 할 수 있고 우리가 어디로 가고 있는지에 대해 조금 더 많은 맥락을 얻을 수있는 이정표입니다. 특정 제한이 존재하는 이유를 이해할 수 있으며 특정 제한이 해제되었음을 알 수 있습니다.

  • C는 안전하지 않은 환경에서 작업하도록 가르 칠 수 있습니다. 즉, 어떤 이유로 든 언어 (어떤 언어)로도 할 수 없거나하지 않을 때 등을 보도록 훈련시킬 수 있습니다. 이렇게하면 버그가 거의 발생하지 않고 안전한 프로그램에서 약간의 속도를 내기 위해 (예 : 포인터 사용) 일시적으로 안전을 끌 수 있기 때문에 안전한 환경에서도 더 나은 프로그래머가 될 수 있습니다. 안전이 런타임 비용과 함께 제공되는 경우 C #에서).

  • C는 모든 객체에 스토리지 요구 사항, 메모리 레이아웃, 유한 주소 공간을 통해 메모리에 액세스 할 수 있다는 사실 등을 알려줄 수 있습니다. 다른 언어에서는 이러한 문제에주의를 기울일 필요가 없지만, 일부 직관을 통해보다 현명한 결정을 내리는 데 도움이되는 경우가 있습니다.

  • C는 빌드 시스템을 통해 링크 및 오브젝트 파일 및 기타 복잡한 세부 사항에 대해 알려줄 수 있습니다. 이를 통해 네이티브 컴파일 된 프로그램이 소스 코드에서 실행으로 이동하는 방식에 대한 유용한 실습을 제공 할 수 있습니다.

  • C는 정의되지 않은 행동의 개념을 통해 새로운 방식으로 생각하도록 마음을 구부릴 수 있습니다. 정의되지 않은 동작은 소프트웨어 개발에서 내가 가장 좋아하는 개념 중 하나입니다. 비 클래식 컴파일러에 미치는 영향에 대한 연구는 다른 언어에서 얻을 수없는 독특한 정신 운동이기 때문입니다. 그러나이 부분을 충분히 이해하기 전에 시행 착오를 거부하고 신중하고 신중하게 언어 공부를 시작해야합니다.

  • 그러나 C가 작은 언어 인 사용자에게 부여 할 수있는 가장 중요한 실현은 모든 프로그래밍이 데이터와 운영으로 귀결 된다는 생각입니다 . 가상 디스패치가있는 계층 구조 및 인터페이스가있는 모듈 식 클래스 또는 순수한 수학 함수를 사용하여 조작되는 우아한 불변 값을보고 싶을 수 있습니다. 그리고 그것은 모두 괜찮습니다. 그러나 C는 그것이 단지 데이터 + 연산 이라는 것을 상기시켜 줄 것입니다 . 그것은 당신이 상당히 많은 정신 장벽을 무너 뜨릴 수 있기 때문에 유용한 사고 방식입니다.


5

C가 학습에 좋은 이유는 어떤 원리도 가르치지 않기 때문 입니다. 일이 어떻게 작동 하는지 가르쳐줍니다 .

C는 70 년대 또는 80 년대의 오래된 오래된 자동차 중 하나와 비교할 수 있습니다. 나사를 찢고 나사로 조이고 각 부품의 작동 방식과 손으로 볼 수있는 다른 부품과 함께 작동하는 방식을 이해할 수 있습니다. 모든 부품을 이해하면 전체 작동 방식을 매우 명확하게 파악할 수 있습니다.

현대 언어는 엔진이 기본적으로 블랙 박스 인 일반 자동차와 비슷하며 일반 자동차 소유자가 이해하기에는 너무 복잡합니다. 그 차는 많은 일을 할 수 있습니다. 요즘에는 스스로 운전하는 법을 배우고 있습니다. 이러한 복잡성과 편의성으로 인해 사용자 인터페이스는 실제로 엔진에서 진행되는 작업에서 훨씬 더 멀어졌습니다.

C에서 프로그래밍을 배우면 컴퓨터로 만들어진 많은 나사와 너트에 닿게됩니다. 이를 통해 기계 자체에 대한 이해를 높일 수 있습니다. 예를 들어, 다음과 같이 긴 문자열을 만드는 것이 좋지 않은 이유를 이해할 수 있습니다.

java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
     result = result + components[i];
};

(이것이 올바른 Java이고, 한동안 사용하지 않았기를 바랍니다 ...)이 코드 예제에서 루프가 2 차 복잡성을 갖는 이유는 분명하지 않습니다. 그러나 이것이 사실이며, 연결할 수백만 개의 작은 구성 요소가있을 때이 코드가 분쇄 중단되는 이유입니다. 숙련 된 C 프로그래머는 문제의 위치를 ​​즉시 알고 있으며 이러한 코드 작성을 피할 수 있습니다.


나는 완전히 동의합니다. C는 일이 어떻게 작동하는지, 이해하기 위해 먼 길을가는 방법에 대해 많은 것을 가르쳐 줄 것입니다. 좋은 지식이 있어야합니다. 그것은 원칙을 가르치지 않고 쉽지 않을 수도 있지만, 그에 대한 존중과 컴퓨터, 그리고 결과적으로 더 높은 수준의 언어에 대한 더 깊은 이해를 얻게 될 것입니다. 또한 Spolsky 조엘에 의해 기본으로 돌아 가기를 읽을 수 : joelonsoftware.com/articles/fog0000000319.html
jleach

1
당신의 대답은 확실하지만 for(int i = 0; i < strlen(s); i++)C로 작성하면 루프는 2 차 복잡성을 갖게되며 Java 예제에서와 마찬가지로 명백하지 않습니다. ;-)
Doc Brown

확실하지는 않지만 Java 컴파일러가 이것을
최적화하도록 믿습니다

숙련 된 Java 프로그래머도 문제의 위치를 ​​즉시 알 수 있으며 이러한 코드를 처음 작성하는 것을 피할 수 있습니다. 이 특정 문제는 기본 Java 자습서에서 설명합니다. 따라서 이것은 C에서 배울 수 있지만 Java에서는 배울 수없는 것이 아닙니다.
피터 테일러

@PeterTaylor C를 아는 Java 강사가 있다면 그렇습니다. 그러나 C를 아는 사람들이 죽은 후에는 이런 종류의 지식이 계속 남아있을 것입니다. C 프로그래머에게는 C-string이 무엇인지에 대한 정의이므로 코드 예제를 효율적으로 사용할 수 없습니다. Java 프로그래머에게는 사용하는 추상화에 대해 깊고, 간결하며 거의 사용되지 않은 지식이므로 이러한 종류의 코드를 피하도록 지시합니다. 좋아, 나는 여기에 약간 과장하고 있지만, 당신은 아이디어를 얻는다 : C 프로그래머는 그것을 알아야만한다. Java 프로그래머는 그것을 모른다면 도망 칠 수있다.
cmaster-monica reinstate 오전

2

"프로그래밍 배후의 원리", 특히 이론적 원리를 배우는 데 C보다 더 나은 언어가 있지만 C는 공예품에 대해 실용적이고 중요한 것들을 배우는 것이 좋습니다. greyfade의 대답은 확실하지만 IMHO는 메모리를 직접 관리하는 방법보다 C에서 배울 수있는 것이 더 많습니다. 예를 들어

  • 예외가없는 상태에서 완전한 오류 처리로 프로그램을 만드는 방법

  • 객체 지향에 대한 언어 지원없이 프로그램에서 구조를 만드는 방법

  • 동적 크기 목록, 사전 또는 유용한 문자열 추상화와 같은 데이터 구조가 없을 때 데이터를 처리하는 방법

  • 컴파일러 또는 런타임 환경이 자동으로 경고하지 않는 경우에도 배열 오버플로와 같은 일반적인 오류를 피하는 방법

  • 템플릿 또는 제네릭에 대한 언어 지원없이 제네릭 솔루션을 만드는 방법

  • 물론 메모리를 직접 관리하는 방법을 배울 수 있다고 언급 했습니까? ;-)

또한 C를 배우면 C ++, Java, C #, Objective C의 구문 공통점이 어디에서 나오는지 알게됩니다.

2005 년 Joel Spolsky는 다른 고급 언어보다 C 학습에 대한 권장 사항 을 작성 했습니다 . 그의 주장은

  • "고급 언어로 효율적인 코드를 만들 수는 없습니다."

  • "최고의 프로그래밍 작업 중 하나 인 컴파일러 및 운영 체제에서는 작업 할 수 없습니다."

  • "대규모 프로젝트를위한 아키텍처를 생성한다고 믿어지지 않을 것입니다"

  • "왜 while(*s++ = *t++);문자열을 복사 하는지 설명 할 수 없거나 그것이 세상에서 가장 자연스러운 것이 아니라면 미신에 기초한 프로그래밍입니다.

물론, 그가 쓴 것은 틀림없이 논쟁의 여지가 있지만 IMHO의 많은 주장은 오늘날에도 여전히 유효합니다.


1
C는 "C가 지원하지 않는다고 생각하는 더 높은 수준의 것들"을 배우기 전에 배우기에는 매우 좋은 언어입니다. 왜냐하면 C가 실제로 작동하는 방식과 그 비용이 얼마나 비싼지를 이해하는 데 도움이되기 때문입니다.
Brendan

@Brendan : 귀하의 의견의 의도가 동의, 의견 불일치 또는 내 답변에 대한 주석을 표현하는 것인지 확실하지 않습니다.
Doc Brown

전문가가 작성한 C 프로그램은 버퍼 오버런 및 하드 충돌로 릴리스됩니다. 따라서 훈련 된 프로그래머 가 이러한 것들을 배우기로 선택할 수도 있지만 , 언어가 본질적 으로 빈곤 한 것만 으로 가르치는 것은 아닙니다 . 예를 들어 예외없이 오류 처리를 수행하고 객체가없는 구조를 만드는 나쁜 방법이 많이 있습니다.
Erik Eidt

@ErikEidt : 사실, 그러나 특히 C 생태계에는 이러한 주제를 다루는 많은 책, 튜토리얼 및 기타 자료가 있습니다. 예를 들어 Steve Maguire의 "Writing Solid Code". 언어 구문을 배우기 위해 K & R의 첫 번째 버전을 선택한 경우에는 더 나은 프로그래머가되지 않을 것입니다.
닥 브라운

1

컴퓨팅의 두 가지 기본 추상화는 튜링 머신과 람다 미적분학이며, C는 튜링 머신의 계산 관점을 실험하는 방법입니다. 그러나 C에는 자체 계산 모델이 제공됩니다. 따라서 C를 배우면 실제 아키텍처와는 상당히 다른 C 추상 머신의 저수준 세부 사항을 배울 수 있습니다. 내가 C에서 배운 첫 번째 것 중 하나는 "영리한"트릭을 적용하여 컴파일러를 능가하려고 시도하지 않았으며, 추세는 컴파일러에서 점점 더 최적화되고있는 것 같습니다. 다른 고급 언어와 마찬가지로 C로 작성할 때 컴파일러는 추상 C 시스템에서 수행 할 작업을 이해하고 실제 하드웨어에서 발생하도록합니다.

C를 배우는 것이 반드시 하드웨어에서 실제로 일어나는 일에 대한 좋은 그림을 제공하지는 않습니다. "C는 기계에 가깝습니다"는 "대부분의 고급 언어보다 더 가깝습니다"로 이해해야합니다. "어떻게 작동하는지"에 대한보다 정확한 그림을 원한다면 소프트웨어 아키텍처를 직접 배우는 것이 더 보람이있을 것입니다.

반면에 학습 C는 시스템 프로그래밍, 저수준 유형, 포인터 및 특히 메모리 할당에 익숙해 질 수 있습니다. 학습 알고리즘 및 데이터 구조에 관해서는 다른 언어가 아닌 C에서 학습하는 이점이 없습니다.


1
그렇다면 C는 고급 언어로는 할 수없는 것을 가르쳐 줄 수 있습니까?
Philip Kendall

2
나는 암시 대답은 생각 : " 아무것도 , 적어도없는 것들 지지자는 일반적으로 주장하는". 어쨌든 대답을 이해하는 방법입니다.
Jörg W Mittag

-3

그것은 매우 개방적인 질문이며, 결정적인 대답을 못합니다. 언어 프레임 워크의 내부를 이해하면 모든 언어로 거의 모든 것을 배울 수 있습니다. C는 기본적으로 운영 체제를 작성하도록 설계되었으므로 세부 정보를 이해하도록합니다. 수년이 지난 후에도 임베디드 시스템과 오픈 소스 프로젝트 덕분에 여전히 가장 많이 사용되는 언어 중 하나입니다. 질문은 당신이 배우고 싶은 것입니까? 그리고 어느 도메인에서?

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