2011-05-15 4 views
3

사실 내가 반복적으로 타이핑하지 않고 반복해야하는 특정 코드 블록을 사용할 수 있도록 루핑을 사용하여 코드를 더욱 효율적으로 만드는 방법을 연구했습니다. 시도한 후 지금까지 배운 것을 사용하여 무언가를 프로그램 할 때 다음 장으로 넘어가 제어 문을 사용하여 프로그램이 지시를 내리는 방법을 배우는 시간이 있다고 생각합니다.C 인수 프로모션에 관한 질문

하지만 내가 사전에 들어가기 전에 나는 이전의 물건에 대한 전문가의 도움이 필요한 질문이 몇 가지 있습니다. 사실 그것은 데이터 유형에 관한 것입니다.


A. 문자 유형

  1. 나는 책 C 프라이머 플러스 5 편에서 다음 추출 :

다소 이상한, C 유형으로 문자 콘스탄스 취급을 char 대신 int입니다. 예를 들어, 32 비트 int와 ASCII 시스템 8 비트 char 에, 코드 :

char grade = 'B'; 

(66)는 32 비트 단위로 저장되어있는 수치로서 'B'을 나타내고 grade ub ab 8 비트 유닛을 66 개 저장 한 상태로 바람을 맞 춥니 다. 문자 상수의이 특성은 'FATE', 과 같은 문자 상수를 으로 정의 할 수 있습니다.이 상수는 4 개의 개별 8 비트 ASCII 코드 이 32 비트 단위로 저장되어 있습니다. 그러나 변수를 변수에 할당하려고 시도하면 변수 결과는 이고 마지막 8 비트는 이므로 값은 'E'이됩니다.

  1. 그래서이 물론 있었다 읽은 후했던 다음 일은, 그것이 내가 char grade와 변수에 단어 FATE를 저장하려고 컴파일하고 무엇을 거 볼려고, 그것은 언급 팔로우 printf()을 사용하여 저장해야하지만, 문자 'E'을 인쇄하는 대신, 내가 얻는 것은 'F'입니다.

  2. 책에 실수가 있습니까? 또는 내가 오해 한 것이 있습니까?

  3. 위의 문장에서 C는 문자 상수를 int으로 처리합니다. 그래서 그것을 시도하기 위해 char 유형에 255 (e.x. 356)보다 큰 숫자를 할당합니다. 356 이후

  4. 그러므로 나는 내가 %d 지정자를 사용할 때 356을 인쇄 할 것으로 예상, 32 비트 int (I 윈도우 7을 실행 해요)의 범위 내에있다.

  5. 그러나 356을 인쇄하는 대신 마지막 8 비트 값인 100이 표시됩니다.

  6. 왜 이런 일이 발생합니까? 나는 char == int == 32-bits을 생각 했는가? (char 앞에는 언급하지 않지만 바이트는입니다.)


B. 지능 및 부동 유형

  1. 내가 short 유형의 변수에 숫자를 저장하는 가변 기능 또는 암시 적 프로토 타입 함수에 전달할 때, 그것은거야 이해 int 유형으로 자동 승격됩니다.

  2. float 유형에 대한 지정은 없습니다 대신에만 %f에 대한이 왜 이것은 또한 float 유형의 부동 소수점 숫자가 전달 될 때, 그것은 double 유형으로 변환 할 수 있습니다, 지점 유형을 떠 일어날

    , 즉 double%Lflong double입니다.

  3. 그러나 승격되었지만 float 유형이 아닌데도 short 유형의 지정자가 있습니까? %hf 또는 이와 비슷한 수식어와 함께 float 유형의 지정자를 제공하지 않는 이유는 무엇입니까? 이것 뒤에 논리적이거나 기술적 인 것이 있습니까? A를

+0

char는 항상 1 바이트이므로 범위를 초과하여 저장할 때 부호없는 경우에는 줄 바꿈됩니다. 랩핑할지 어떨지는 구현에 의존하지만, 일반적으로 -ve에 랩합니다. 필자는 '운명'문제는 기계 바이트 순서 및 아마도 구현 의존성과 관련이 있다고 생각한다. 출력으로 'E'를 얻는다. – phoxis

+1

바이트 단위로 8 비트를 의미한다면, 그렇지 않습니다. http://www.ibm.com/developerworks/power/library/pa-ctypes1/#N1007D – Joe

+4

제발, 한 번에 10 가지 질문을하지 마십시오. 이것은 토론 포럼이 아닙니다. –

답변

0

: 3)이 크고 작은 엔디안 CPU의 achitectures의 다른 바이트 순서 부를 때문이다. 리틀 엔디안 (즉, x86)의 첫 번째 바이트와 빅 엔디안 CPU의 마지막 바이트 (즉 PPC)를 가져옵니다. 실제로 char에 대한 변환 fom int가 완료되었지만 int의 문자가 역순으로 저장되면 항상 가장 낮은 8 비트를 얻습니다.

7.) char에는 8 비트 만 저장할 수 있기 때문에 int를 char 변수에 할당하고 나중에 char 변수에서 복원 할 수없는 모든 항목이 잘립니다.

To B : 3.) 상위 변수에 관계없이 int 변수의 하위 16 비트 만 인쇄하려고 할 때가 있습니다. 특정 최적화를 위해 단일 변수에 여러 정수 값을 채우는 것은 일반적이지 않습니다. 이것은 정수형에 대해서는 잘 작동하지만 비트 연산을 직접 지원하지 않는 부동 소수점 형에 대해서는별로 중요하지 않습니다. 이는 printf에 float에 대한 별도의 유형 지정자가 없기 때문일 수 있습니다.

+0

char는 ** 적어도 ** 8 비트를 보유 할 수 있습니다. 테스트를 마친 컴퓨터에서 정확히 8 비트 인 것처럼 보이지만 이는 언어의 요구 사항이 아닙니다. –

1

우선, char이고, 정의는 정확히 1 바이트이다. (AFAIK)

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 

정확한 크기는 시스템과 컴파일러에 의해 (char 제외) 다양하지만 32 비트 Windows에서 GCC와 VC와 크기는 다음과 같습니다 : 그런 다음 표준 어느 정도는 크기가되어야한다고 말한다 : 이 경우 'E'대 'F'의

sizeof(short) == 2 (byte) 
sizeof(int) == sizeof(long) == 4 (byte) 

귀하의 관찰은 (는 "단어"가 메모리에 저장되어 얼마나 큰 엔디안, 대 작은) 전형적인 엔디안 문제입니다.

이제 가치는 어떻게됩니까? 8 비트 너비의 변수가 있습니다. 더 큰 값 ('FATE' 또는 356)을 할당하지만 컴파일러는 8 비트 만 저장할 수 있다는 것을 알고 있으므로 다른 모든 비트를 잘라냅니다.

0

char은 1 바이트입니다. 바이트의 비트 길이는 8, 16, 32 비트가 될 수 있습니다. 범용 컴퓨터에서 일반적으로 문자의 비트 길이는 8 비트입니다. 따라서 캐릭터가 표현할 수있는 최대 숫자는 캐릭터의 비트 길이에 달려 있습니다. 문자 체크 limits.h 헤더 파일의 비트 길이를 확인하려면이 파일에 CHAR_BIT으로 정의됩니다.

char x = 'FATE'은 기계/컴파일러가 '운명'을 해석 할 바이트 순서에 따라 달라질 수 있습니다. 따라서 이것은 시스템/컴파일러에 달려 있습니다. 누군가 확인하고 수정하십시오.

시스템에 8 비트의 바이트가있는 경우 char 데이터에는 항상 1 바이트의 저장 공간이 할당되므로 c = 360의 경우 이진 표현의 하위 8 비트 만 변수에 저장됩니다. 따라서 %d은 변수에 값을 할당 할 때 상위 비트가 손실되고 왼쪽에있는 것은 하위 8 비트이므로 100을 인쇄합니다.

+0

C 바이트가 8 비트라고 가정합니다. :-) –

+0

확실히 암시 적입니다. 우리는 범용 컴퓨터에서 바이트 주소 지정 가능한 메모리를 가지고 있으며, 대부분의 핸드 헬드 및 모든 컴퓨터에서 사용할 수 있습니다. – phoxis

+0

@phosix - 요점은 ** (삽입 된 장치에서) 16 비트 또는 32 비트처럼 ** 더 클 수 있다는 것입니다. 이 경우 값 360은 char에 맞을 것입니다. –

2

하나의 질문에 많은 질문은 ... 여기에 몇 가지에 대한 답변은 다음과 같습니다

문자 상수의 이러한 특성은 가능와 같은 '운명'같은 문자 상수를 정의 할 수 있습니다

네 개의 개별 (8) - 비트 ASCII 코드는 32 비트 단위로 저장됩니다. 그러나 이러한 문자 상수를 char 변수에 할당하려고하면 마지막 8 비트 만 사용되므로 변수의 값이 'E'가됩니다.

이것은 실제로 구현이 정의한 동작입니다. 그렇습니다. 책에 실수가 있습니다. C에 관한 많은 책은 세계의 유일한 C 컴파일러가 예제를 테스트 할 때 사용한 저자라는 가정하에 작성되었습니다.

저자가 사용한 컴파일러는 'FATE'의 문자를 'F'가 최상위 바이트이고 'E'가 최하위 인 정수로 처리했습니다. 컴파일러는 리터럴의 문자를 inteder의 바이트로 취급합니다. 'F'가 최하위 바이트이고 'E'가 가장 중요합니다. 예를 들어 첫 번째 방법은 MSVC가 값을 처리하는 방법이며 MinGW (Windows를 대상으로하는 GCC 컴파일러)는 두 번째 방법으로 리터럴을 처리합니다.

지금까지와 같은이 double을 기대 지정자에 float을 기대 printf()에는 형식 지정자 인 없습니다 - 서식 printf()에 전달 된 값이 변수 인수 목록의 일부입니다 때문입니다합니다 (...printf()의 프로토 타입) . 이러한 인수에 대한 정보는 입력하지 않으므로 컴파일러에서 항상 C99 6.5.2.2/6 "함수 호출"에서이를 승격시켜야합니다.

호출 된 함수를 나타내는 식에 형식이 프로토 타입을 포함하지 않는 경우 정수 승격은 각 인수에서 수행되고 float 형식의 인수는 double로 승격됩니다. 이를 기본 인수 판촉이라고합니다.

및 C99 6.5.2.2/7 "함수 호출"

함수 원형 선언자의 줄임표 표기법은 마지막 선언 된 매개 변수 뒤에 인수 형식 변환이 중지되도록합니다. 기본 인수 승격은 후행 인수에서 수행됩니다.

그래서 효과에, 그것은 floatprintf()에 전달하는 것은 불가능합니다 - 그것은 항상 double으로 승격됩니다. 이것이 부동 소수점 값의 형식 지정자가 double을 필요로하는 이유입니다. short 포맷에 대한 h 지정이 반드시 필요한 경우 당신이 얻을하려는 경우가 n 지정자와 함께 사용하기 위해 필요하지만 short에 적용 할 것입니다 자동 홍보로 인해 또한

, 나는 (솔직히 잘 모르겠어요 short에있는 스트림에 기록 된 문자 수). n 지정자, 역사적인 이유 또는 내가 생각지 못했던 것을 지원하기 위해 거기에 있어야하기 때문에 C에있을 수 있습니다.

+0

+1 문자가 1보다 큰 정수 문자 상수의 값은 ISO C99 §6.4.4.4 ¶10에 따라 구현 정의되어 있습니다. – ninjalj