FPGA 같은 하드웨어를 사용하다보면, 가끔 데이터가 꼬일 때, Endianness 문제일 까 싶을 때가 있다.

간단한 C 코드를 통해 System의 Endianness 를 확인 할 수 있다.

 

예 1) 전처리기 활용

#if __BYTE_ORDER == __LITTLE_ENDIAN
	printf("Little Endian\n");
#elif __BYTE_ORDER == __BIG_ENDIAN
	printf("Big Endian\n");

예 2) Pointer 활용

int x = 1;
char* cp = &x;

if(*cp == 1){
	printf("Little Endian\n");
}
else{
	printf("Big Endian\n");
}

 

'Programming > C Language' 카테고리의 다른 글

C progress printing  (0) 2018.08.07
static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

wget 등 사용 시 Progress가 프린팅 된다.

Carriage return(\r) 과 fflush를 활용하면 이쁘게 Progress를 print 할 수 있다.


percent = (float)i*100/(MEM_SIZE/sizeof(int));

printf("\r[");

for(j=0; j<50; j++){

if(j<(int)percent/2)

        printf(">");

else

printf(" ");

}

printf("]%.2f%%",percent);

fflush(stdout);


'Programming > C Language' 카테고리의 다른 글

Check the system's Endianness  (0) 2019.04.23
static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

일반적으로 C언어에서, 지역 변수는 함수 내에서 존재하고, 함수가 종료되는 시점에 사라지게 된다.

이때 사라지지 않고 기존의 값을 보존하게 하기 위한 keyword 가 static 이다.


static keyword를 사용하면, 지역 변수가 함수 종료 때 사라지지 않고, 값을 보존하게 된다.


주의!!! static은 전역 변수에서 사용하여, 다른 파일에서 extern 해서 사용할 수 없다.

'Programming > C Language' 카테고리의 다른 글

Check the system's Endianness  (0) 2019.04.23
C progress printing  (0) 2018.08.07
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20

C언어에서 stdarg.h 헤더를 사용하면 함수 선언 시 가변 인자(Variable arguments)를 가질 수 있다.


stdarg.h 헤더파일은 자료형으로 va_list를 가지며, 함수로 va_start, va_arg, va_end 등의 함수를 포함하고 있다.


아래의 예를 살펴보면 이해 할 수 있을 것이다.

#include<stdio.h>

#include<stdarg.h>


void vaPrintf(const char* sentence, ...){

int i;

va_list values;

va_start(values, sentence);

unsigned long long int iInt64;

double* iDouble_p;


for(i=0;;i++){

if(sentence[i] == 0) break;

else if(sentence[i] == '%'){

i++;

switch(sentence[i]){

case 'd' : printf("%d", va_arg(values, int));

break;

case 'c' : printf("%c", va_arg(values, unsigned int));

break;

case 'f' : printf("%f", (float)va_arg(values, double));

break;

case 's' : printf("%s", va_arg(values, char*));

break;

case 'x' : printf("%x", va_arg(values, unsigned int));

break;

case 'l' : if(sentence[i+1] == 'd'){

printf('%ld", va_arg(values, unsigned long long int));

}

else if(sentence[i+1] == 'f'){

printf("lf", va_arg(values, double));

}

else{

printf("ERROR: invalid format\n");

}

break;

defaut : printf("ERROR: invalid format\n");

break;

}

}

else{

printf("%c", sentence[i]);

}

}

}


void main(){

vaPrintf("vaPrintf test\n");

vaPrintf("int 1 = %d\n", (int)1);

vaPrintf("float 1.5 = %f\n", (float)1.5);

vaPrintf("double 1.5 = %lf\n", (double)1.5);

}

주의 해야할 점은 va로 float 을 넘기게 되면 넘어갈 때 double 형태로 넘어가게 된다고한다.(short, char 등도 int로 넘어간다.)

따라서 va_arg(va_list _list, type _t) 에서 type은 float 이 될 수 없다.

다만, function_call 시 float 을 인자로 넘긴다면, 이와같이 va_arg(_list, double) double 로 지정하더라도 할당 받는 변수의 형태에 맞춰 자동으로 float 으로 변환이 된다.(할당 받는 변수가 float 이면 float으로 자동으로 캐스팅/ double 이면 double로)

이와 같은 이유로, printf 함수에서도 double 자료형을 출력할 떄, %f / %lf 아무거나 써도 똑같이 double 형 캐스팅된 값을 출력하게 된다.


추가적으로 ARMCC 의 경우, 가변인자로 double/unsigned long long int 등 32bit 을 넘어가는 데이터가 제대로 넘어가지 않는 오류를 발견했다.

넘기기 전에 32비트씩 나누어 넘기고, 받아서 다시 data type을 바꿔주는 것이 좋을 듯 하다.





'Programming > C Language' 카테고리의 다른 글

C progress printing  (0) 2018.08.07
static  (0) 2018.07.13
extern  (0) 2017.06.21
static  (0) 2017.06.20
Floating Point Bit 출력 방법  (0) 2017.06.08

extern keyword 


일반적으로 전역 변수를 선언 하면, 한 파일 내에서 전역 변수로 접근이 가능하다.

다른 파일에서 선언된 전역 변수를 접근하기 위해서는 extern keyword 를 사용한다.


사용법은 간단하다.

전역 변수 선언 시 일반적으로 선언 하듯 선언 하고,

접근하고자 하는 다른 파일에서 data type 앞에 extern 을 선언하면, 접근이 가능하다.

int a=5;


extern int a;

printf("a=%d in other file", a);

//print result

//a=5

extern keyword 를 사용하면 다른 파일에서 접근이 가능하기 떄문에, 즉, 다른 파일에서 해당 이름의 변수를 가지고 있기 때문에

같은 이름의 변수를 두 개를 가지는 등의 의도치 않은 동작을 할 수 있다.

사용 시에 주의가 필요하다.


extern keyword 의 또다른 사용법이 있다.

C++ 파일을 사용하는데, C로 된 파일/함수 등을 include 하고 싶은 경우!

extern "C"{

#include <stdio.h>

void foo();

}


'Programming > C Language' 카테고리의 다른 글

static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
static  (0) 2017.06.20
Floating Point Bit 출력 방법  (0) 2017.06.08
전처리기 명령어  (0) 2017.06.07

static Keyword


기본적인 C/C++ 프로그래밍에서 흔히 사용하는 키워드는 아니다.

하지만, Code 가 여러 파일로 구성되고, 여러 파일에서 서로 참조하고 왔다갔다하면서 부터 사용하게 되는 keyword 일 수 있다.


static 은 정적 변수라고 하는데, 

함수 내부에 선언하는 지역 변수는 그 지역이 사라지면서, 함께 사라지는데 이를 방지 하기 위한 keyword 이다.

함수 내부의 변수를 data type 앞에 static 을 붙여 선언하면, 메모리 위치에서 사라지지 않아, 

다음에 함수가 call 되더라도 이전 값을 유지하고 있다.

다만 여전히 지역 변수이기 때문에, 해당 함수에서만 읽고 쓸 수 있다.

static 으로 선언한 변수의 initialize 는 처음 한 번 만 실행 된다.

void function(){

static int a = 1;

print("%d\t", a);

a++;

}


int main(){

function(); //print result : 1

function(); //print result : 2

function(); //print result : 3

return 0;

}


'Programming > C Language' 카테고리의 다른 글

static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
Floating Point Bit 출력 방법  (0) 2017.06.08
전처리기 명령어  (0) 2017.06.07

Floating Point 방식의 변수를 Bit 그대로 출력하는 방법


1. Union 활용

Union은 같은 메모리 주소에 여러가지 형태로 값을 저장하는 변수이다.

union{

float a;

int b;

};

a(float)에 값 저장 후 b(int) 출력


또는 typedef를 활용하여 아래와 같이 구성하면 된다.

typedef union{

float float_t;

int int_t;

}int_float_t;


int_float_t a;

a.float_t = 3.14;

printf("%x\n", a.int_t);


2. Pointer 활용

float a = 1.2345; //float value

int* b = (int*)&a;

*b를 출력

'Programming > C Language' 카테고리의 다른 글

static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20
전처리기 명령어  (0) 2017.06.07

#define, #include 등 C/C++ 에서 사용되는 #으로 시작되는 것들은 전처리기 명령어 혹은 전처리기 지시문(preprocessing directives)라 한다.

전처리기 명령어를 통해 컴파일 과정을 Control 할 수 있다.

전처리기 명령어는 반드시 독립된 Line 의 시작에 위치해야 한다.


#include

일반적으로 가장 많이 쓰이는 전처리기 명령어인 #include는 헤더파일을 포함시키기 위해 사용된다.

#include <stdio.h>

#include "my_header.h"

* 꺾쇠(<>)로 묶인 header 파일은 일반적인 header 파일 디렉토리에 있는 헤더파일, 큰따옴표("")로 묶인 header 파일은 사용자 지정 경로에 있는 헤더파일


#define

#define 은 자주 쓰이는 숫자를 문자로 정의하여, 다른 사람들이 알아보기 쉽게 만들어 주는 역할을 한다. 

#define PI 3.14

* #undef 로 정의 한 것을 풀어 줄 수 있음


#ifdef / #ifndef / #endif 등을 함께 활용하여, 컴파일 시 조건을 변경하기 용이하게 코드를 작성하기도 한다.

일반적으로, 헤더파일의 시작과 끝에 작성하여, 헤더파일을 여러곳에서 포함(include)시키더라도, 헤더파일을 중복으로 참조 방지(include guard / macro guard / header guard)의 방법으로 사용된다.

/****header file name is A.h******/

#ifndef A_H_

#define A_H_

// header file contents

#endif


#define 을 이용하여 매크로 함수를 만들 수 있다.

#define SQUARE(x) x*x



#if / #elif / #else / #endif

#if / #elif / #else / #endif 를 통해 compile 의 조건을 Control 한다.


#pragma

#pragma 는 전처리기 명령어를 정의하는 전처리기 명령어 이다. 

일반적으로, 아래와 같이 once 라는 전처리기 명령어를 정의해 헤더파일 중복 참조를 방지한다.

/*****header file *****/

#pragma once

// header file contents

* 위의 #ifndef / #define / #endif 를 이용해 헤더파일 중복 참조를 방지 한 것과 같은 역할을 함.

* pragma 를 support 하지 않는 compiler의 경우 무시됨

'Programming > C Language' 카테고리의 다른 글

static  (0) 2018.07.13
가변 인자(variable arguments) stdarg.h  (0) 2017.12.11
extern  (0) 2017.06.21
static  (0) 2017.06.20
Floating Point Bit 출력 방법  (0) 2017.06.08

+ Recent posts