블로그 이미지

[C언어][개발역량평가] 자료형(Data Type)의 크기(Size)

2013. 8. 19. 23:55

ANSI/ISO C 표준에 보면 다음과 같이 나와 있습니다.

 

short should be at least 16bits and long should be at least as long as int, but not smaller than 32 bits.

 

대충 번역해보면, short 는 최소한 16 bit 가 되어야 하며, long 은 적어도 int 크기보다는 크고 32 bit 보다는 작지 않아야 합니다. int 크기는 short 와 long 의 사이에 들어가면 되겠네요.

 

가장.큰 차이점은 얼마나 큰 정수를 나타낼 수 있나 하는 것인데, bit 의 크기를 보고 알수 있습니다. 0 에서 2의 bit 수 승-1만큼 표현이 가능하죠(부호형은 절반)

 

거의 모든 C 컴파일러는 위의 표준을 따르며 보통 CPU(물론 운영체제도 지원해야 함) 에 따른 각 자료형의 크기는 다음과 같습니다.

 

16 bit CPU:

  - short int : 16bit

  - int : 16bit

  - long int : 32bit

32 bit CPU:

  - short int : 16bit

  - int : 32bit

  - long int : 32bit

64 bit CPU:

  - short int : 16bit

  - int : 32bit

  - long int : 64bit

 

물론 위의 각 자료형 크기는 기본적인 크기입니다. 컴파일러에 따라, 운영체제에 따라, 컴파일러 옵션을 주기에 따라 자료형의 크기는 달라질 수 있습니다. 자신의 컴퓨터에서 sizeof 를 사용해서 각 자료형의 크기를 구해볼 수 있습니다.

 

그리고  short int 를 줄여서 short 라고 쓰며, long int 를 줄여서 long 이라고 씁니다. auto 를 생략하는 것과 비슷하죠. 함수내에서 쓰는 변수들은 모두 앞에 auto 가 생략되어 있습니다. 물론 명시적으로 이름을 다 써줘도 상관 없습니다. 다음의 두 문장은 함수내에서 같습니다.

 

short a;

 

auto short int a;



블로그 이미지

[C언어][개발역량평가] Struct(구조체), Union(공용체) size(크기) 에대한 정리

2013. 8. 19. 23:15

1. Struct

Struct(구조체)는 구조체 멤버중 가장 큰 변수의 크기를값을 기준으로 잡고 기준값의 크기에 나머지 변수를 순서대로 차곡 차곡 배치하여 구조체의 전체 크기가 결정 된다. 아래의 예시 코드를 보자.

#include

typedef struct test{ int a; long c; char b; char d:1, //d:1의 의미는 char d를 1bit 의 크기로 계산하고 사용한다는 의미 e:1, f:1, g:2, i:1, k:1; long h; } test; int main(void) { test k; k.g=1; // printf("a:%d \n",k.g); printf("size : %d\n",sizeof(k)); return 0; }

구조체 형태 도식화 (long 은 64bit 운영체제에서 8byte 이다. 아래의 표는 64bit 기준)

int (4byte)

 

 

 

 

long (8byte)

Char(1)

Char(1)

 

 

 

 

 

 

Long (8byte)

 

test struct의 사이즈는 얼마일까요? 64bit 머신을 기준으로  32byte이다. (long 8byte)
의아하지 않나요? 보통은 int (4byte), char(1byte)이므로, 총 4+8+1+1+8 = 22byte 라고 여길텐데 말입니다.


2. Union

Union(공용체)의 크기는 공용체 멤버 변수 중 가장 큰 크기의 값을 하나 할당하고 모든 멤버가 그 메모리를 공유하게 된다.

typedef union {

    char a;
    int b;
    long c;

} Aion

공용체 형태 도식화

Long (8 bytes) { char(1 byte), int(4 bytes) }

공용체 Aion의 크기는 얼마일까요? 공용체 멤버 중 가장 크기가 큰 long 형을 기준으로 8 bytes 크기를 사용하고 나머지 멤버들이 이 메모리 공간을 모두 공유 하게 됩니다. 즉, 13 bytes 도 아니고 16 bytes 도 아니고 8 bytes 가 되는 겁니다.


Struct(구조체) vs Union(공용체) 메모리 사용 비교






블로그 이미지

[C언어][개발역량평가] printf 서식 문자

2013. 8. 19. 22:34

printf 서식문자

서식문자

출력 대상(자료형)

출력 형태

%d

int

부호 있는 10진수 정수

%u

unsigned int

부호 없는 10진수 정수

%o

unsigned int

부호 없는 8진수 정수

%x, %X

unsigned int

부호 없는 16진수 정수

%f

float, double

10진수 방식의 부동소수점 실수

%e, %E

float, double

또는 방식의 부동소수점 실수

%g, %G

float, double

값에 따라 %f와 %e 사이에서 선택

%c

char

값에 대응하는 문자

%s

char *

문자열

%p

void *

포인터의 주소 값

%n

int *

포인터의 주소 값

 

printf(“%#7.5hd”);

A B C D

A : 출력의형태에조절을가하기위한특별한표시문자(#)

좌측정렬

0 : 빈공갂을0으로채우기

+ : 출력할수의크기가0보다클때, + 기호붙여주기

공백출력할수의크기가0보다클때수의앞에빈칸하나출력

# : 8진수, 16진수출력시 각각00x실수의경우소수점이하출력

B : 출력에사용되는최소한의폭(7)

C : 정밀도(5)

D : 출력데이터의크기정보변경(h)


블로그 이미지

[Linux] GCC 사용 예제

2013. 8. 9. 17:58

gcc 사용 패턴 예제


test.c 라는 코드가 있다고 치자.


1) 컴파일, 링크, 빌드(a.out):  test1.c  소스코드를 컴파일하고 기본 라이브러리와 링크 과정을 거쳐 실행 파일을 빌드 한다. 빌드 된 실행 파일은 a.out 이라는 이름을 가진다.

(a.out 은 Assembly out을 뜻한다.)

gcc test1.c
결과물: a.out

2) 컴파일, 링크, 빌드(-o 옵션, 특정이름):  test1.c  소스 코드를 컴파일하고 기본 라이브러리와 링크 과정을 거쳐 실행 파일을 빌드 한다. 빌드 된 실행 파일은 -o 옵션 뒤에 붙은 이름을 가진다.

gcc test1.c -o test

결과물: test


3) 컴파일(-c 옵션): bill.c 와 jane.c 소스 코드를 컴파일하여 목적 파일만 만든다.

(소스 코드 내에 main 함수가 없는 경우에도 컴파일 된다.)

gcc -c bill.c jane.c
결과물 : bill.o jane.o


4) 링크 및 빌드(-o 옵션): bill.o 와 jane.o 목적 파일을 링크 하여 빌드 된 실행 파일을 만든다.

gcc -o test test1.o test2.o
결과물: test

5) 헤더파일 수동 옵션(-i 옵션): 헤더 파일을 찾을 때 표준 장소들과 함께 /usr/openwin/include 에서 찾는다.

gcc -I /usr/openwin/include fred.c
결과물: test.o



블로그 이미지

[C언어] #if #endif 조건부 컴파일

2013. 2. 20. 19:10

1) 조건부 컴파일

전처리문이므로 컴파일되기 전에 조건을 평가하며 코드를 컴파일 대상에 포함시키거나 제외시키는 역할을 한다. 이때 조건의 형태는 여러 가지가 있지만 주로 매크로 상수의 존재 여부나 값에 대한 평가식이 사용된다.

 

#ifdef, #ifndef

2) #if

 

if는 매크로의 값을 평가하거나 여러 가지 조건을 결합하여 컴파일 여부를 결정하는 좀 더 복잡한 전처리문이다

#if 조건1

코드1           // 조건1을 만족하면 코드1을 컴파일

#elif 조건2

코드2           // 조건 2가 만족되면 코드2를 컴파일

#else

코드3           // 둘 다 맞지 않으면 코드 3을 컴파일

#endif

 

(1) 상등, 비교 연산자 사용이 가능하다.

==, != ,  >, <, >=, <=

(2) 비교 대상은 정수 상수만, 실수, 문자열은 안됨

(3) 논리 연산자 사용 가능

 &&, ||, !

ex) #if (LEVEL == 8 && VER != 3)

(4) defined 연산자로 매크로의 존재 여부를 평가 할 수 있다.

ex) #if (LEVEL == 8 || defined(PROFESSIONAL))

ex) #if (defined(_DX_8) || defined(_DX_9))

[출처] #if defined 사용법|작성자 clous02


블로그 이미지

[C언어] 가변인자함수

2013. 2. 18. 18:06



1. 가변 인자함수

함수의 전닮값(파라미터)(인수) 의 개수가 정해져 있지 않은 함수다.

ex) printf, scanf


2. 가변 인수

인수의 개수와 타입이 정해져 있지 않은 인수


3. 가변인수함수 : 가벼인수(...)를 이용한 함수

#include <stdarg.h> //일반 적인 가변 인수 함수의 구조 void VarFunc(int Fix, ...) { va_list plter; va_star(plter, Fix);
while() //모든 인수를 다 읽을 때 까지 { va_arg(pValue, 인수타입); } va_end(pValue); 

} 


가. va_list : 전달된 인수들은 스택에 저장되고 함수는 스택에서 인수를 꺼내 쓴다.

va_list타입은 char*형으로 정의됭져 있고 가변이수를 읽기 위한 포인터 변수이다.


나. va_start(plter, 마지막 고정 인수), plter포인터변수가 첫번째 가변인수를 가리키도록 초기화 한다.

마지막 고정인수의 번지에 길이를 더해서 가변인수가 시작되는 번지를 계산한다.


다. va_arg(plter, 인수타입) 가변인수를 실제로 읽는 명령어, plter 위치에서 인수타입에 맞는 값을 읽어 리턴하여 plter를 다음 가변 가변인수 위치로 옮겨준다. va_arg는 매크로 함수이기 때문에 타임명이 내부적으로 sizeof연산자와 캐스트 연산자로 전달되어 인수로 받을 수 이싿.


라. va_end(plter) 가변인수로 다 읽은후 뒷정리하는데 별다른 동작은 하지 않는다.




블로그 이미지

[C언어] scanf 기본 서식문자 조합

2013. 2. 16. 17:22


정말 보시다시피 %c와 %hhd의 차이가 있죠?

여러분이 아실점은 %c와 %hhd는 다르다는것과, h는 자료형을 한단계 감소한다는겁니다.


그렇다면 반대로, 한단계 증가시키는건 무엇일까요? 앞에서 말했던 l(L) 입니다
  • %d : int
  • %ld : long
  • %lld : long
  • %f : float
  • %lf : double
  • %Lf : long double
주의 하실점은 lf와 Lf는 서로 다르다는것이죠.

예제를 통해봅시다.

역시 차이점은 자리수가 늘어난거입니다.

그냥 단순해요, 좀더 공간이 넓어진것

이로서 11-2 scanf 기본 서식문자 조합을 마치겠습니다.

여담이지만 컴파일하시다가 종종 "에이 그냥 Lf, lld로 하지, 귀찮게 %d,%lf 가있는거야"

이런생각하실텐데, 공간의 낭비와 효율성을 위하여 각각 구분한겁니다. 현재는 코딩해도 10K,30K밖에

용량이 않나오지만, 좀더 큰 소프트웨어는 1G, 10G하지 않습니까? 이럴수록 최적화 하는거죠.

다음은, 12-1 비트단위 연산자 를 포스팅하겠습니다. 감사합니다!


블로그 이미지

[C언어] Printf 의 %lf, %f와 Scanf의 %lf, %f의 차이

2013. 2. 16. 17:08


질문 : double형은 scanf를 할 때, 왜 %lf를 해줘야 하고 printf를 할 때는 %f 로 해주어야 하나?


답 : 

printf 는 포인터가 아닌 값을 받기 때문에 파라미터 리스트에서 각각의 데이터

크기를 알 수 있습니다.

포맷 문자가 f 이고 파라미터 크기가 4면 float로 처리하고

포맷 문자가 f 이고 파라미터 크기가 8이면 double로 처리하게 됩니다.

 

scanf는 입력을 받아야 하니까 모든 파라미터를 포인터로 받게 되죠.

하지만, 포인터는 그 주소값 4byte만 전달될 뿐

해당 포인터가 가리키는 자료형이 무엇인가는 전달되지 않습니다.

즉, scanf가 전달받는 포인터는 void타입 포인터라고 보면 됩니다.

      그렇기 때문에 float와 double을 f lf로 구분해줘야 하는 거죠.

 

물론 사용자가 만든 함수도 파라미터 전달시 타입정보는 전달되지 않습니다.

받을 수 있는 타입이 첨부터 고정되어 있을 뿐이죠. scanf처럼 타입이 가변형인

경우는 타입 정보를 명시해줄 수 있는 수단이 필요하겠죠. 그게 포맷정보입니다.

  1. 2019.03.17 22:10  address  modify / delete  reply

    감사합니다.

  2. 2019.08.29 01:42  address  modify / delete  reply

    감사합니다~


블로그 이미지

C언어에서 #include<>와 #include"" 지시어의 차이점

2012. 5. 29. 04:03

<>를 쓸 경우 Visual Studio 내부에 설치되어 있는 헤더파일을 사용한다는 것이고,


""를 쓸 경우는 프로젝트의 로컬영역, 즉 같은

폴더내에 저헤더파일이있으니 저걸 추가시키겠다. 라고 컴파일러에게 알려주는것입니다.