programing

C 데이터형은 어떻게 "대부분의 컴퓨터에서 직접 지원"됩니까?

goodsources 2022. 12. 19. 21:46
반응형

C 데이터형은 어떻게 "대부분의 컴퓨터에서 직접 지원"됩니까?

저는 K&R의 "The C Programming Language"를 읽고 있는데 우연히 다음과 같은 문구를 접하게 되었습니다[개요, 페이지 3].

C가 제공하는 데이터 유형 제어 구조는 대부분의 컴퓨터에서 직접 지원되므로 자체 포함 프로그램을 구현하는 데 필요한 런타임 라이브러리는 매우 작습니다.

굵은 글씨는 무슨 뜻입니까?컴퓨터에서 직접 지원하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?

네, 직접 지원되지 않는 데이터 유형이 있습니다.

대부분의 임베디드 시스템에는 하드웨어 부동소수점 유닛이 없습니다.이렇게 코드를 작성하면

float x = 1.0f, y = 2.0f;
return x + y;

다음과 같이 변환됩니다.

unsigned x = 0x3f800000, y = 0x40000000;
return _float_add(x, y);

그 후 컴파일러 또는 표준 라이브러리는 다음과 같은 구현을 제공해야 합니다._float_add()임베디드 시스템의 메모리를 사용합니다.아주 작은 시스템에서 바이트 수를 세는 경우, 이는 합산될 수 있습니다.

하나의 정수64')입니다.long long C 시스템에 의해 되지 않습니다.1999년 C 표준에서는 32비트 시스템이 직접 지원되지 않습니다.이전 SPARC 시스템은 정수 곱셈을 지원하지 않았기 때문에 실행 시 곱셈을 제공해야 했습니다.또 다른 예가 있습니다.

기타 언어

그에 비해 다른 언어들은 더 복잡한 원형을 가지고 있다.

예를 들어 Lisp 기호는 Lua의 테이블, Python의 문자열, Fortran의 배열 등과 같이 많은 런타임 지원이 필요합니다.C의 동등한 타입은 보통 표준 라이브러리의 일부가 아니거나(표준 심볼이나 테이블이 없음), 훨씬 단순하고 런타임 지원을 많이 필요로 하지 않습니다(C의 어레이는 기본적으로 포인터일 뿐이며 눌 종단 문자열은 거의 단순합니다).

제어 구조

C에서 누락된 주목할 만한 제어 구조는 예외 처리입니다.는 '출구'로 됩니다.setjmp() ★★★★★★★★★★★★★★★★★」longjmp()프로세서 상태의 특정 부분을 저장하고 복원합니다.이에 비해 C++ 런타임은 스택을 워킹하고 디스트럭터 및 예외 핸들러를 호출해야 합니다.

사실 이 서론의 내용은 1978년 Kernighan과 Ritchie가 초판에 처음 쓴 이후 크게 변하지 않았고, 현대 구현보다 당시 C의 역사와 진화를 더 많이 언급했을 것이다.

컴퓨터는 기본적으로 메모리 뱅크와 중앙 프로세서일 뿐이며 각 프로세서는 기계 코드를 사용하여 동작합니다. 프로세서의 설계의 일부는 조립 언어라고 불리는 명령 집합 아키텍처로, 사람이 읽을 수 있는 니모닉 세트에서 기계 코드(모두 숫자)로 일대일 매핑됩니다.

C 언어(및 그 바로 앞의 B 언어 및 BCPL 언어)의 저자들은 가능한 한 효율적으로 어셈블리에 컴파일된 언어의 구성을 정의하는 데 주력하고 있었습니다.실제로 타겟 하드웨어의 제약에 의해 어쩔 수 없이 작성되었습니다.다른 답변에서 지적한 바와 같이 여기에는 브런치(GOTO 및 C의 기타 흐름 제어), 이동(할당), 논리 연산(& | ^), 기본 연산(더하기, 빼기, 증가, 감소) 및 메모리어드레싱(포인트)이 포함됩니다.좋은 예로는 C의 pre/post-increment 및 decrement 연산자를 들 수 있습니다.이 연산자는 컴파일 후 단일 opcode로 직접 변환할 수 있기 때문에 특히 Ken Thompson에 의해 B언어에 추가되었을 것으로 생각됩니다.

이것이 저자들이 "대부분의 컴퓨터에서 직접 지원"이라고 말한 것의 의미입니다.이는 다른 언어에 직접 지원되지 않는 유형 및 구조가 포함되어 있다는 것을 의미하는 것이 아니라 설계상 C 구조가 어셈블리로 가장 직접(때로는 문자 그대로 직접) 변환된다는 을 의미합니다.

구조화된 프로그래밍에 필요한 모든 요소를 제공하면서도 기초가 되는 의회와의 밀접한 관계가 C의 조기 채택을 이끌어 냈으며, 코드 컴파일 효율이 여전히 중요한 환경에서 C가 오늘날 널리 사용되는 언어로 유지되고 있습니다.

언어의 역사에 대한 흥미로운 기록은 C 언어의 발전 - Dennis Ritchie참조하십시오.

간단히 말하면, C가 지원하는 대부분의 언어 구조는 대상 컴퓨터의 마이크로프로세서에서 지원되므로 컴파일된 C 코드가 마이크로프로세서의 어셈블리 언어로 매우 훌륭하고 효율적으로 번역되므로 코드와 설치 공간이 줄어듭니다.

긴 답변에는 약간의 어셈블리 언어 지식이 필요합니다.C에는 다음과 같은 문장이 있습니다.

int myInt = 10;

조립 시 다음과 같은 결과를 얻을 수 있습니다.

myInt dw 1
mov myInt,10

이것을 C++와 비교해 주세요.

MyClass myClass;
myClass.set_myInt(10);

결과적으로 생성되는 어셈블리 언어 코드(MyClass()의 크기에 따라 다름)는 최대 수백 개의 어셈블리 언어 라인을 추가할 수 있습니다.

어셈블리 언어로 프로그램을 실제로 만들지 않고 순수 C는 프로그램을 만들 수 있는 가장 얇고 엄격한 코드일 수 있습니다.

편집

제 답변에 대한 코멘트를 고려하여, 저는 단지 제 정신으로 테스트를 해보기로 결정했습니다.저는 "test.c"라는 프로그램을 만들었는데, 이 프로그램은 다음과 같습니다.

#include <stdio.h>

void main()
{
    int myInt=10;

    printf("%d\n", myInt);
}

저는 이것을 gcc를 사용하여 어셈블리로 정리했습니다.다음 명령줄을 사용하여 컴파일했습니다.

gcc -S -O2 test.c

다음으로 어셈블리 언어를 나타냅니다.

    .file   "test.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d\n"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB1:
    .section    .text.startup,"ax",@progbits
.LHOTB1:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB24:
    .cfi_startproc
    movl    $10, %edx
    movl    $.LC0, %esi
    movl    $1, %edi
    xorl    %eax, %eax
    jmp __printf_chk
    .cfi_endproc
.LFE24:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE1:
    .section    .text.startup
.LHOTE1:
    .ident  "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
    .section    .note.GNU-stack,"",@progbits

그런 다음 "test.cpp"라는 파일을 만듭니다.이 파일은 클래스를 정의하고 "test"와 같은 내용을 출력합니다.c":

#include <iostream>
using namespace std;

class MyClass {
    int myVar;
public:
    void set_myVar(int);
    int get_myVar(void);
};

void MyClass::set_myVar(int val)
{
    myVar = val;
}

int MyClass::get_myVar(void)
{
    return myVar;
}

int main()
{
    MyClass myClass;
    myClass.set_myVar(10);

    cout << myClass.get_myVar() << endl;

    return 0;
}

다음 명령을 사용하여 동일한 방법으로 컴파일했습니다.

g++ -O2 -S test.cpp

결과 어셈블리 파일은 다음과 같습니다.

    .file   "test.cpp"
    .section    .text.unlikely,"ax",@progbits
    .align 2
.LCOLDB0:
    .text
.LHOTB0:
    .align 2
    .p2align 4,,15
    .globl  _ZN7MyClass9set_myVarEi
    .type   _ZN7MyClass9set_myVarEi, @function
_ZN7MyClass9set_myVarEi:
.LFB1047:
    .cfi_startproc
    movl    %esi, (%rdi)
    ret
    .cfi_endproc
.LFE1047:
    .size   _ZN7MyClass9set_myVarEi, .-_ZN7MyClass9set_myVarEi
    .section    .text.unlikely
.LCOLDE0:
    .text
.LHOTE0:
    .section    .text.unlikely
    .align 2
.LCOLDB1:
    .text
.LHOTB1:
    .align 2
    .p2align 4,,15
    .globl  _ZN7MyClass9get_myVarEv
    .type   _ZN7MyClass9get_myVarEv, @function
_ZN7MyClass9get_myVarEv:
.LFB1048:
    .cfi_startproc
    movl    (%rdi), %eax
    ret
    .cfi_endproc
.LFE1048:
    .size   _ZN7MyClass9get_myVarEv, .-_ZN7MyClass9get_myVarEv
    .section    .text.unlikely
.LCOLDE1:
    .text
.LHOTE1:
    .section    .text.unlikely
.LCOLDB2:
    .section    .text.startup,"ax",@progbits
.LHOTB2:
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB1049:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $10, %esi
    movl    $_ZSt4cout, %edi
    call    _ZNSolsEi
    movq    %rax, %rdi
    call    _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE1049:
    .size   main, .-main
    .section    .text.unlikely
.LCOLDE2:
    .section    .text.startup
.LHOTE2:
    .section    .text.unlikely
.LCOLDB3:
    .section    .text.startup
.LHOTB3:
    .p2align 4,,15
    .type   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, @function
_GLOBAL__sub_I__ZN7MyClass9set_myVarEi:
.LFB1056:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $_ZStL8__ioinit, %edi
    call    _ZNSt8ios_base4InitC1Ev
    movl    $__dso_handle, %edx
    movl    $_ZStL8__ioinit, %esi
    movl    $_ZNSt8ios_base4InitD1Ev, %edi
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    jmp __cxa_atexit
    .cfi_endproc
.LFE1056:
    .size   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi, .-_GLOBAL__sub_I__ZN7MyClass9set_myVarEi
    .section    .text.unlikely
.LCOLDE3:
    .section    .text.startup
.LHOTE3:
    .section    .init_array,"aw"
    .align 8
    .quad   _GLOBAL__sub_I__ZN7MyClass9set_myVarEi
    .local  _ZStL8__ioinit
    .comm   _ZStL8__ioinit,1,1
    .hidden __dso_handle
    .ident  "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
    .section    .note.GNU-stack,"",@progbits

명확하게 알 수 있듯이 어셈블리파일은 C++ 파일보다 C+ 파일 쪽이 훨씬 커집니다.다른 것은 모두 잘라내고, C의 메인과 C++의 메인만을 비교해도, 여분의 것이 많이 있습니다.

K&R은 대부분의 C 표현식(기술적 의미)이 지원 라이브러리에 대한 함수 호출이 아니라 하나 또는 몇 개의 어셈블리 명령에 매핑된다는 것을 의미합니다.일반적인 예외는 하드웨어 div 명령이 없는 아키텍처의 정수 분할 또는 FPU가 없는 시스템의 부동 소수점입니다.

다음과 같은 견해가 있습니다.

C는 어셈블리 언어의 유연성과 파워를 어셈블리 언어의 사용자 친화성과 결합합니다.

(여기에 있습니다.'어셈블리 언어의 속도와 어셈블리 언어의 편리함과 표현성' 등 다른 변형이 생각났다고 생각했습니다.

long int는 보통 네이티브 머신의 레지스터와 같은 너비입니다.

일부 상위 수준의 언어는 데이터 유형의 정확한 폭을 정의하며, 모든 기계에서 구현은 동일하게 작동해야 합니다.하지만 C는 아니야.

x86-64 또는 임의의 크기의 BigInteger에서 128비트 int를 사용하는 경우 함수 라이브러리가 필요합니다.현재 모든 CPU는 음의 정수를 2진수로 표현하기 위해 2s 보정을 사용하고 있지만, C가 설계되었을 때는 그렇지 않았습니다.(그렇기 때문에 2s가 아닌 기계에서는 다른 결과를 얻을 수 있는 것이 C 표준에서는 기술적으로 정의되어 있지 않습니다.)

데이터 또는 함수에 대한 C 포인터는 어셈블리 주소와 동일한 방식으로 작동합니다.

참조를 다시 계산하려면 직접 수행해야 합니다. 다른 하는 c 경우 C++ C++ 이외의 많은 .call★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

문자열은 어레이에 불과합니다.

라이브러리 기능 외에 제공되는 문자열 조작은 문자 읽기/쓰기뿐입니다.searchnul-terminated)로 됩니다)'\0'포인터 + 길이가 아닌 8비트 정수 배열이므로 서브스트링을 얻으려면 원래 문자열에 nul을 입력해야 합니다.)

CPU는 문자열 검색 함수에 의해 사용하도록 설계된 명령어가 있는 경우가 있지만, 일반적으로 실행되는 명령당 1바이트를 루프에서 처리합니다.(또는 x86 rep prefix를 사용합니다).C가 x86 상에서 설계되었을 경우 문자열 검색 또는 비교는 라이브러리 함수 호출이 아닌 네이티브 조작일 수 있습니다.)

다른 많은 답변에서는 예외 처리, 해시 테이블, 목록 등 기본적으로 지원되지 않는 예를 제공합니다.K&R의 디자인 철학은 C가 기본적으로 이러한 것을 가지고 있지 않은 이유입니다.

프로세스의 어셈블리 언어는 일반적으로 점프(이동), 스테이트먼트, 이동 스테이트먼트, 바이너리 관절염(XOR, NAND, OR 등), 메모리 필드(또는 주소)를 취급합니다.메모리를 명령과 데이터의 두 가지 유형으로 분류합니다.어셈블리 언어란 이것뿐입니다(어셈블리 프로그래머들은 이것보다 더 많은 것이 있다고 주장할 것입니다만, 대체로 이렇게 요약됩니다).C는 이 단순성과 매우 유사합니다.

C는 대수학과 산술의 관계를 정리하는 것이다.

C는 어셈블리의 기본(프로세서 언어)을 캡슐화합니다."C가 제공하는 데이터 유형과 제어 구조가 대부분의 컴퓨터에서 직접 지원되기 때문에"보다 더 진실한 표현일 수 있습니다.

오해의 소지가 있는 비교에 주의하다

  1. 이 선언은 적어도 주류 고급 언어의 경우 그 이후로 대부분 구식이 된 "런타임 라이브러리"라는 개념에 의존하고 있습니다.(최소한의 임베디드 시스템에도 해당됩니다).런타임은 라이브러리에 의해 제공되는 함수를 명시적으로 호출하는 것이 아니라 언어에 내장된 구성만 사용하는 경우 해당 언어의 프로그램이 실행해야 하는 최소한의 지원입니다.
  2. 이와는 대조적으로 현대 언어는 런타임 라이브러리와 표준 라이브러리를 구별하지 않는 경향이 있으며, 표준 라이브러리는 종종 상당히 광범위합니다.
  3. K&R 서적 발행 당시 C씨는 표준 도서관이 없었다.오히려 사용 가능한 C 라이브러리는 Unix의 다른 플레이버 간에 상당히 차이가 있었습니다.
  4. 스테이트먼트를 이해하려면 표준 라이브러리(다른 답변에서 언급된 Lua 및 Python 등)를 사용하는 언어와 비교하지 말고 더 많은 빌트인 구성 요소(예: 다른 답변에서 언급된 기존 LISP 및 FORTRAN)를 사용하는 언어와 비교해야 합니다.다른 예로는 BASIC(LISP와 같은 인터랙티브)나 PASCAL(FORTRAN과 같은 컴파일)이 있습니다.둘 다 언어 자체에 입력/출력 기능이 내장되어 있습니다.
  5. 반면 라이브러리가 아닌 런타임만 사용하는 C 프로그램에서 계산 결과를 얻을 수 있는 표준 방법은 없습니다.

컴퓨터에서 직접 지원하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?

모든 기본 데이터 유형과 C 언어의 조작은 루프 없이1개 또는 몇 개의 기계어 명령으로 구현할 수 있습니다.이러한 명령어는 (실제로 모든) CPU에 의해 직접 지원됩니다.

일반적인 데이터 유형 및 그 조작에는 수십 개의 기계어 명령이 필요하거나 일부 런타임 루프의 반복 또는 둘 다 필요합니다.

많은 언어에는 이러한 유형 및 그 동작에 대한 특별한 축약 구문이 있습니다.일반적으로 C에서 이러한 데이터 유형을 사용하는 경우에는 훨씬 더 많은 코드를 입력해야 합니다.

이러한 데이터 유형 및 운영에는 다음이 포함됩니다.

  • 임의 길이 텍스트 문자열 조작 - 연결, 하위 문자열, 다른 문자열로 초기화된 변수에 새 문자열 할당 등('s = "Hello World!" , s = (Python의 s + s)[2:-2])
  • 놓다
  • C++ 및 기타 모든 객체 지향 프로그래밍 언어에서와 같이 중첩된 가상 파괴자를 가진 객체
  • 2D 행렬 곱셈 및 나눗셈, 선형 시스템 해결(MATLAB 및 많은 배열 프로그래밍 언어에서 "C = B / A; x = A\b")
  • 정규 표현
  • 가변 길이 배열 -- 특히 항목을 배열 끝에 추가하는 경우 메모리를 더 할당해야 할 수 있습니다.
  • 런타임에 유형을 변경하는 변수의 값을 읽습니다.때로는 부동이고,때로는 문자열입니다.
  • 어소시에이션 어레이(종종 '보통' 또는 '보통'이라고 불린다)
  • 리스트
  • 비율(「+ 1/3 2/7」은 Lisp의 「13/21」을 나타냅니다)
  • 임의의 계산(종종 '비그넘'이라고 불린다)
  • 데이터를 인쇄 가능한 표현으로 변환(JavaScript의 ".tostring" 메서드)
  • 포화 고정 소수점 수(종종 임베디드 C 프로그램에서 사용)
  • 런타임에 입력된 문자열을 식(많은 프로그래밍 언어에서 "eval()")인 것처럼 평가합니다.

이 모든 조작에는 수십 개의 기계어 명령이 필요하거나 거의 모든 프로세서에서 실행 시 루프를 반복해야 합니다.

수십 개의 기계어 명령이나 루프가 필요한 일반적인 제어 구조에는 다음과 같은 것이 있습니다.

  • 폐쇄
  • 속행
  • 예외
  • 나태한 평가

C 또는 다른 언어로 작성되었든 간에 프로그램이 이러한 데이터 유형을 조작할 때 CPU는 최종적으로 이러한 데이터 유형을 조작하기 위해 필요한 모든 명령을 실행해야 합니다.그 지침들은 종종 "도서관"에 포함되어 있다.C를 포함한 모든 프로그래밍 언어에는 기본적으로 모든 실행 파일에 포함된 각 플랫폼에 대한 "런타임 라이브러리"가 있습니다.

컴파일러를 쓰는 대부분의 사용자는 "언어에 내장된" 모든 데이터 유형을 조작하는 명령을 런타임 라이브러리에 넣습니다.C에는 상기 데이터 타입과 조작 및 제어 구조가 언어에 포함되어 있지 않기 때문에 C 런타임라이브러리에 포함되어 있지 않기 때문에 C 런타임라이브러리는 언어에 내장되어 있는 다른 프로그래밍 언어의 런타임라이브러리보다 작아집니다.

프로그래머가 C 또는 그가 선택한 다른 언어로 "언어에 내장되지 않은" 다른 데이터 유형을 조작하기 위해 프로그램을 원할 때, 그 프로그래머는 일반적으로 컴파일러에게 그 프로그램에 추가 라이브러리를 포함하도록 지시하거나 때때로 (의존관계를 피하기 위해) 이러한 작업의 다른 구현을 직접 작성합니다.n 프로그램

「」에 짜넣어진 입니까?C이런 거 있잖아요int,char,* int,float 등 , 레이등...CPU를 사용CPU는 어레이를 사용하는 방법, 포인터를 참조 해제하는 방법 및 포인터, 정수 및 부동소수점 숫자에 대한 산술 수행 방법을 알고 있습니다.

하지만 고급 프로그래밍 언어로 넘어가면 추상 데이터형과 더 복잡한 구조를 구축하게 됩니다.예를 들어 C++ 프로그래밍 언어로 구성된 광범위한 내장 클래스를 살펴 보십시오.CPU는 클래스, 오브젝트 또는 추상 데이터 타입을 인식하지 않기 때문에 C++ 런타임은 CPU와 언어 사이의 갭을 메웁니다.다음은 대부분의 컴퓨터에서 직접 지원되지 않는 데이터 유형의 예입니다.

퓨퓨컴르르르르르 르에서는 C'PDP-11long(전부는 아니지만 일부 32비트 조작을 지원하는 옵션 애드온모듈을 구입할 수 있었습니다).원본 IBM PC를 포함한 모든 16비트 시스템의 다양한 수준에서도 마찬가지입니다.또한 32비트 머신이나 32비트 프로그램에서의 64비트 조작도 마찬가지입니다만, K&R 북의 시점에서는 C언어에는 64비트 조작이 전혀 없었습니다.(386 포함)이직접 하지 않는 도 있습니다(80 년 90 년 386 、 486 ) 。또한 오늘날에는 부동소수점 연산을 직접 지원하지 않는 임베디드 시스템도 일부 있었습니다.float ★★★★★★★★★★★★★★★★★」double를 참조해 주세요.

더 예로 는 " 포인터 것)와 바이트 포인터 " " " " " " " " 2 " " ) 、 " 4 " )만 지원합니다char * ★★★★★★★★★★★★★★★★★」void *)는 추가 오프셋필드를 추가하여 구현해야 합니다. 질문은 그러한 시스템에 대해 좀 더 자세히 설명합니다.

"런타임 라이브러리" 함수는 매뉴얼에서 볼 수 있는 함수가 아니라 머신에서 지원되지 않는 기본 유형의 작업을 구현하기 위해 사용되는 최신 컴파일러의 런타임 라이브러리에서 볼 수 있는 것과 같은 함수입니다.K&R이 언급한 런타임 라이브러리는 Unix Heritage Society 웹사이트에서 찾을 수 있습니다.ldiv) 또, (C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C는 C가 됩니다.PDP-11은 애드온을 사용해도 지원되지 않는32비트 값의 분할을 실장하기 위해 사용됩니다.csv (그리고)cret또한 csv.c)에서는 콜 및 함수로부터의 반환을 관리하기 위해 스택에 레지스터를 저장 및 복원합니다.

또한 기본 머신에 의해 직접 지원되지 않는 많은 데이터 유형을 지원하지 않는 선택을 언급하고 있을 가능성이 있습니다.이는 CPU의 기본 포인터 지원에도 매핑되지 않는 어레이 시멘틱스를 C의 어레이처럼 가지고 있는 FORTRAN과 같은 다른 현대 언어와는 다릅니다.C 어레이는 항상 제로 인덱스이며 첫 번째 어레이 이외의 모든 랭크에서 항상 사이즈가 알려져 있다는 사실은 어레이의 인덱스 범위나 크기를 저장할 필요가 없다는 것을 의미합니다.또한 이들 어레이에 액세스하기 위해 런타임 라이브러리 함수가 필요하지 않습니다.컴파일러는 필요한 포인터 산술만 하드 코드할 수 있습니다.

이 문장은 단순히 C의 데이터와 제어 구조가 기계 지향적이라는 것을 의미합니다.

여기서 고려해야 할 두 가지 측면이 있습니다.하나는 C 언어에는 데이터 타입의 정의(ISO 표준)가 있기 때문에 데이터 타입의 정의 방법에 대한 관용도를 확보할 수 있다는 것입니다., C 언어의 실장은 머신에 맞추어 조정됩니다.C 컴파일러의 데이터 유형은 컴파일러가 대상으로 하는 머신에서 사용 가능한 것과 일치합니다.왜냐하면 이 언어는 컴파일러에 대한 관용도를 가지고 있기 때문입니다.기계가 36비트와 같은 비정상적인 워드 크기를 가지고 있다면,int ★★★★★★★★★★★★★★★★★」long을 사용하다 로 한 int32번

둘째, 이러한 휴대성 문제로 인해 두 번째 효과가 있습니다.어떻게 보면 K&R의 발언은 일종의 자기충족적 예언이 되거나 혹은 그 반대일 수 있다.즉, 새로운 프로세서의 구현자는 C 컴파일러의 지원이 절실하다는 것을 인식하고 있으며, "모든 프로세서가 80386처럼 보인다"고 가정하는 많은 C 코드가 존재한다는 것을 알고 있습니다.아키텍처는 C를 염두에 두고 설계되어 있습니다.C뿐만 아니라 C의 휴대성에 대한 일반적인 오해도 염두에 두고 있습니다.당신은 단순히 9비트 바이트의 기계나 다른 어떤 것을 더 이상 일반적인 용도로 도입할 수 없습니다.그 유형이 다음과 같이 가정하는 프로그램char8시휴대성 전문가가 작성한 일부 프로그램만이 계속 작동합니다.툴 체인, 커널, 사용자 공간 및 유용한 응용 프로그램을 합리적인 노력으로 통합하기에는 충분하지 않을 수 있습니다.할 수 있는 C프로그램이 작성된입니다.

컴퓨터에서 직접 지원하지 않는 데이터 유형 또는 제어 구조의 예가 있습니까?

여러 기계 언어에서 직접 지원되지 않는 데이터 유형: 다중 정밀도 정수, 링크 목록, 해시 테이블, 문자열.

제어 구조는 대부분의 기계 언어에서 직접 지원되지 않습니다. 퍼스트 클래스 연속, 코루틴/스레드, 제너레이터, 예외 처리.

이 모든 작업에는 다수의 범용 지침을 사용하여 작성된 상당한 런타임 지원 코드와 더 많은 기본 데이터 유형이 필요합니다.

C에는 일부 시스템에서 지원되지 않는 표준 데이터 유형이 있습니다.C99부터 C에는 복소수가 있습니다.두 개의 부동소수점 값으로 만들어지며 라이브러리 루틴과 함께 작동합니다.일부 기계에는 부동소수점 단위가 전혀 없습니다.

일부 데이터 유형에 대해서는 명확하지 않습니다.하나의 레지스터를 기본 주소로 사용하고 다른 레지스터를 스케일링된 치환으로 사용하여 메모리의 주소 지정을 지원하는 머신의 경우 어레이가 직접 지원되는 데이터 유형임을 의미합니까?

또한 부동소수점이라고 하면 IEEE 754 부동소수점이라는 표준화가 있습니다.에 C가 이유double프로세서가 지원하는 부동소수점 형식과 일치하는 것은 두 가지 방식이 일치했기 때문만이 아니라 해당 표현에 대한 독립적인 표준이 있기 때문입니다.

예를 들어

  • 목록 거의 모든 기능 언어로 사용됩니다.

  • 예외입니다.

  • 연관 배열(Maps) - PHP 및 Perl 등에 포함되어 있습니다.

  • 가비지 컬렉션

  • 여러 언어로 구성되지만 CPU에서 직접 지원되지 않는 데이터 유형/제어 구조입니다.

직접 지원은 프로세서의 명령 세트에 효율적으로 매핑하는 것으로 이해해야 합니다.

  • 긴(확장 연산 루틴이 필요할 수 있음) 및 짧은 크기(마스크가 필요할 수 있음)를 제외하고 정수 유형을 직접 지원하는 것이 규칙입니다.

  • 부동소수점 유형을 직접 지원하려면 FPU를 사용할 수 있어야 합니다.

  • 비트 필드에 대한 직접 지원은 예외입니다.

  • 구조 및 어레이에는 주소 계산이 필요하며, 어느 정도 직접 지원됩니다.

  • 포인터는 항상 간접 주소 지정을 통해 직접 지원됩니다.

  • goto/if/while/for/do는 무조건/조건부 브랜치에서 직접 지원됩니다.

  • 스위치는 점프 테이블 적용 시 직접 지원할 수 있습니다.

  • 함수 콜은 스택 기능을 통해 직접 지원됩니다.

언급URL : https://stackoverflow.com/questions/27977522/how-are-c-data-types-supported-directly-by-most-computers

반응형