728x90
/* 섭씨 온도 입력하면 화씨 온도 반환 CelToFah 함수
그 반대 FahToCel 함수 정의및 호출
Fah=1.8 x Cel+32 */

#include <stdio.h>

double CelToFah(double c)
{
	return 1.8*c + 32;
}

double FahToCel(double f)
{
	return (f - 32) / 1.8;
}

int main()
{
	int select;
	double num;

	printf("1. 섭씨℃->화씨℉	2. 화씨℉->섭씨℃-\n");
		printf("선택:");
		scanf("%d", &select);

	if (select == 1)
	{
		printf("섭씨℃ 입력: ");
			scanf("%lf", &num);
		printf("섭씨℃->화씨℉: %f \n", CelToFah(num));
	}
	else if (select == 2)
	{
		printf("화씨℉ 입력:");
			scanf("%lf", &num);
		printf("화씨℉->섭씨℃: %f \n", FahToCel(num));
	}

	return 0;
}


Output:







/* 인자로 전달된 수만큼의 피보나치 수열을 출력하는 함수
5를 입력하면 5! */

#include <stdio.h>

void Fibo(int num)
{
	int f1 = 0;
	int f2 = 1;
	int f3;
	int i;

	if (num == 1)
		printf("%d ", f1);
	else
		printf("%d %d ", f1, f2);

	for (i = 0;  i<num-2;  i++) // 0과 1일 경우는 위의 if~else문에서 출력
	{
		f3 = f1 + f2;
		printf("%d ", f3);
		f1 = f2;
		f2 = f3;
	}
}

int main()
{
	int n;
	printf("출력하려는 피보나치 수열갯수 (1이상 입력) : ");
	scanf("%d", &n);

	if (n < 1)
	{
		printf("1 이상 값 입력하세요 \n");
		return -1;
	}
	Fibo(n);
	return 0;
}


Output:






최대 공약수(Greatest Common Measure) 구하기 (유클리드 호제법 이용)

알고리즘

  1. 두 수 n1,n2 입력
  2. n이 0이라면, n2 출력하고 알고리즘 종료.
  3. n이 n2를 나누어 떨어지면, n을 출력하고 알고리즘 종료.
  4. 그렇지 않으면, n2를 n1로 나눈 나머지를 새롭게 n2에 대입하고, n2와 n1을 바꾸고 3.으로 돌아온다.


예를 들어 6, 12의 GCM을 구할 때, 12가 6을 나누어 떨어지니 6을 출력하고 알고리즘을 종료한다.

#include<stdio.h>

int GCM(int n1, int n2);


int main(void)
{
	int n1;
        int n2;

	printf("두 개의 정수 입력: ");
	scanf("%d %d", &n1, &n2);

	printf("GCM : %d \n", GCM(n1, n2));
	return 0;
}

int GCM(int n1, int n2)
{
	int result;
	result = n1;
	while(n1%result !=0 || n2%result !=0)
		result--;
	return result;
}

이 문제에선 6, 9의 GCM을 구한다면,

int result;
	result = n1;
	while(n1%result !=0 || n2%result !=0)
		result--
n1=6, result=6

6과 6을 나눈 나머지는 0,     9와 6을 나눈 나머지는 3이므로 
=0 (false) || !=0 (true) 가 된다.

따라서 result--가 되고 while을 반복해나가다보면
6%3=0 || 9%3=0 이 되어 while문을 빠져나가고 result값인 3을 return하며 종료된다.



728x90

1. 디지털이란?

digit - 손가락


analog->표본화(sampling)->양자화->부호화



불확정성의 원리



임베디드 레시피 p.28

저항, 인덕터, 캐패시터



R (저항)

전류의 흐름을 방해. 저항의 크기가 크면 작은 전류, 저항의 크기가 작으면 큰 전류가 흐를 수 있음



L(인덕터) 또는 코얼

저주파수는 통과

고주파수는 걸러진다.

주로 회로에 직렬연결


C(캐패시터) 또는 콘덴서

고주파 통과

저주파 걸러냄

주로 회로에 병렬연결




'Study > Embedded' 카테고리의 다른 글

7 Segment 출력(proteus시뮬)  (0) 2016.05.16
5/12 avr 업무일지  (0) 2016.05.12
2016 04 28 디코더  (0) 2016.04.28
2016 04 27 논리회로  (0) 2016.04.27
2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
728x90


디코더


입력선에 나타나는 n비트의 2진 코드를 최대 2n개의 서로 다른 정보로 바꿔주는 조합논리회로


 

2x4 디코더 진리표





AND 게이트로 구현한 2x4 디코더                                        실제 회로는 NAND 게이트로 구현


: NAND 게이트를 사용하는것이 AND 게이트를 사용한 디코더에 비해 게이트를 더 적게 쓰기 때문에 경제적.

성능 측면에서도 NOT 게이트의 신호전달 지연시간 만큼을 줄일 수 있기 때문






'Study > Embedded' 카테고리의 다른 글

5/12 avr 업무일지  (0) 2016.05.12
5/2 디지털이란? / 저항, 인덕터, 캐패시터  (0) 2016.05.02
2016 04 27 논리회로  (0) 2016.04.27
2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
728x90

OR : 논리합 








AND : 논리곱








HD74LS00P (NAND 게이트)



http://www.alldatasheet.co.kr/datasheet-pdf/pdf_kor/247357/RENESAS/HD74LS00P.html








NAND로 NOT 게이트 만들기




NAND로 NOT 게이트 만들기



Output :

A = Lo: Out = Hi

A = Hi: Out = Lo

A = Lo: Out = Hi

A = Hi: Out = Lo






NOR 게이트(74HC02)




입력들 중 `1`이 1개 이상이면 출력이 `0`이 됨 

입력이 모두 `0`인 경우에만 출력이 `1`이 됨


A = Lo, B = Lo: Out = Hi

A = Lo, B = Hi: Out = Lo

A = Hi, B = Lo: Out = Lo

A = Hi, B = Hi: Out = Lo




XOR 게이트
: 입력 값이 같으면 0을 출력하고, 입력 값이 다르면 1을 출력

A

B

XOR B

0
0
1
1

0
1
0
1

0
1
1
0










Carry와 Sum (Carry는 올림수, Sum은 합을 의미)
: 10진수 1+9는 논리합이 0이 되고 자리올림 1이 되는 것처럼, 2진수도 똑같이 생각하면 된다.

가산기(Adder)

반가산기

A + B = C / S
0    0    0    0
0    1    0    1
1    0    0    1
1    1    1    0

여기서 carry는 and,

sum은 xor 게이트와 같다.

A

B

XOR B

0
0
1
1

0
1
0
1

0
1
1
0


반가산기 논리회로







전가산기

2개의 비트 a,b와 자리올림 Ci를 더해 합 S와 자리올림 Co을 구한다.  (Carry input/ Carry output)


입력

출력

A

B

Ci

Co

S

0

0

0

0

0

0

0

1

0

1

0

1

0

0

1

0

1

1

1

0

1

0

0

0

1

1

0

1

1

0

1

1

0

1

0

1

1

1

1

1


전가산기 논리회로 예시



'Study > Embedded' 카테고리의 다른 글

5/2 디지털이란? / 저항, 인덕터, 캐패시터  (0) 2016.05.02
2016 04 28 디코더  (0) 2016.04.28
2016-04-25_디지털제어-회로 기초  (0) 2016.04.25
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
728x90

analog 연속 -> noise에 약함, 데이터량에 많음, 원래 신호에 가까움, 보안성 약함



digital 불연속 -> noise에 강함



ADC 

:표본화, 양자화, 부호화를 거쳐 digital화 함



충전을 위해선 20%이상의 전압을 걸어줘야 함




전류 Current    A

전압 Voltage    V

저항 Resistor    R   



DC 직류 - 주파수 0 Hz



AC 교류 - 주파수 60 Hz




SMPS(Switched-Mode Power Supply) 

AC Line 주파수(50㎐~60㎐)를 DC로 변환하여 높은 주파수로 변경 (수십 ㎑~수백 ㎑)하여 사용





AC 단상 3선식 (일명 돼지코)

Live(Hot), Neutral(Cold) // N, L이라고 쓰여있음

  아래위엔 접지(Earth)가 있음



회로 설계시

1. 전자부품의 스펙 확인

구동전압 확인


2. 회로 설계

3. Artwork

4. Debugging

5. Artwork


싱크/ 소스타입 조사하기





풀업&풀다운 저항


어정쩡한 요인을 제거하기 위해 풀업이나 풀다운 저항을 사용함. 확실한 high와 low로 만들어줌

풀업 풀다운을 위해하기전에 플로팅에 대해 알 필요가 있다.



 플로팅 (floating)


 칩에 입력을 5V 또는 0V를 가한다. 하지만 입력을 가하지 않는 경우는 칩 자체에서는 5V를 입력하였는지 1V를 입력하였는지 모른다. 이런 문제에 의하여 오작동이 발생할 수 있다. 이런 상태를 플로팅되었다라고 한다. 플로팅 상태는 잡음에 매우 취약해지므로 시스템이 불안정해진다. 이를 해결 하기 위해서 풀업 / 풀다운 저항을 사용하게 된다



풀업 저항 (Pullup resistor)


풀업 저항을 사용한다면 스위치가 열려 있을 때 칩에는 항상 5V의 전압이 가해진다. 
따라서 회로에 입력을 몰라도 항상 5V의 전압을가진 상태가 된다. 스위치를 닫는다면 그라운드 쪽으로 전류가 흐르게 되며 회로의 전압은 0V가 되며, 1을 입력한 것으로 인식하게 된다. 핀을 높은 저항에 매달아 둔다는 뜻에서 '풀 업 저항'이라 한다.


풀다운 저항 (Pulldown resistor)


회로는 5V의 전압을 받으면 1로 인식하고, 0V의 전압을 받으면 0으로 인식한다. 
스위치가 열려있는 상태에서 그라운드와 연결되어 있으므로 전류가 항상 그라운드로 흐르게 되어 0V가 된다. 스위치를 닫게되면 소량의 전류가 저항을 통해 그라운드로 흘러 나가지만 많은 양의 전류가 회로(핀)로 흘러 5V가 된다. 따라서 1이 입력된 것으로 인식한다. 항상 그라운드에 묶어둔다는 의미에서 '풀 다운 저항' 이라 한다.




http://air802.tistory.com/2


슈미트 트리거 회로

Schmitt Trigger는 미국의 과학자 Otto H. Schmitt에 의해 발명된 일종의 비교기로써, 하나의 입력 전압과 출력 전압, 두 개의 threshold를 가진다. positive feedback을 사용하는 비교기로, OP Amp의 구조를 가지며 대부분 inverter로 사용된다.


 

 

 즉, input 신호로 low threshold 보다 낮은 전압이 인가되면 출력은 high로, high threshold 보다 높은 전압이 인가되면 출력은 low가 되며, 두 개의 threshold 사이의 전압이 인가되면 그 값을 유지한다.


 threshold가 하나인 유사한 시스템의 경우, 입력 신호에 noise가 섞여 threshold에 비슷한 전압이 인가되면 스위치를 순식간에 on/off 시킬 수 있기 때문에 두 개의 threshold를 사용하는 Schmitt Trigger가 더 안정적이다. 그러므로 사람의 손 떨림으로 인해 값이 여러번 입력되는 등의 switch noise를 제거할 수 있다.




http://blog.naver.com/PostView.nhn?blogId=davidsbkim&logNo=150031720819




임베디드 레시피

http://recipes.egloos.com/


도쳬 : 금속, 흑연 ...

부도체: 전류가 흐르지 않음


반도체 - 다이오드 : 한쪽 방향으로만 전류 흐름.


순방향


순방향 전압


역방향


역방향 전압



트랜지스터

http://www.mully.net/lee/2015/transistor/



대부분의 트랜지스터는 3개의 다리를 가지고 있습니다. 각각 베이스(Base), 컬렉터(Collector), 이미터(Emitter)라고 부릅니다.

  • 베이스(B): 트랜지스터를 작동시키기 위해 약한 전기신호를 가하는 단자입니다.
  • 컬렉터(C): 베이스에(B) 약한 전기신호가 들어오면 막혀 있던 컬렉터(C)에 큰 전류가 흐르게 됩니다.
  • 이미터(E): 베이스(B)와 컬렉터(C)에서 흐르는 전류가 합쳐지는 단자입니다.



Trans-Resistor :  Resistor값을 변화 시킬 수 있다는 의미로 전류의 양을 조절하는 것.







 B에 넣어주는 전압(전류)량의 미묘한 변화에도 저항값이 휙휙 많이 바뀐며, 결국 EC간의 전류 값도 휙휙 변하게 된다.





주파수






디지털 샘플링  Digital Sampling

http://www.mully.net/lee/2015/digital_sampling/


자연의 모든 소리는 아날로그 신호입니다.

아날로그 정보는 연속적인 모든 시간에서의 정보를 가지고 있습니다. 모든 시간의 값을 전부 기록할 수는 없으므로 보통은 일정한 시간 간격마다 값만 기록을 할 수 밖에 없습니다. 즉, 값을 추출하는 적당한 시간 간격을 정해야 합니다.

아날로그 정보를 디지털 정보로 정확하게 기록하기 위해서는 기록을 하는 시간 간격도 충분히 작게 해야 합니다. 즉, 아날로그 정보가 변하는 특정 시간 보다 더 촘촘한 시간 간격으로 기록을 해야 합니다.




접지(Earthing, Grounding) : 각종 전기, 전자, 통신 설비들을 전기적으로 대지와 연결하여 전위를 대지와 같은 기준전위(0 v)로 만드는 것






74 HC 시리즈 각 칩의 기능과 구성


http://donghwada.tistory.com/entry/74HC-%EC%8B%9C%EB%A6%AC%EC%A6%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%ED%8A%B8-%EB%B3%B4%EB%8A%94-%EB%B2%95-%EB%B0%8F-%EC%A0%95%EB%A6%AC74HC00-74HC02-74HC04-74HC08-74HC32-74HC86




'Study > Embedded' 카테고리의 다른 글

2016 04 28 디코더  (0) 2016.04.28
2016 04 27 논리회로  (0) 2016.04.27
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
20160322_펌웨어(USART)  (0) 2016.03.22
728x90

구조체와 배열


연관되었지만 타입이 다른 자료형의 경우는 구조체, 

같은 경우는 배열 사용



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>

struct person
{
    char name[20];
    char phoneNum[20];
    int age;
};

int main()
{
    struct person man1, man2;
    strcpy(man1.name, "안성준");
    strcpy(man1.phoneNum, "010'1122-3344");

    return 0;
}


위의 소스를 아래와 같이 비유할 수 있다.



 붕어빵 기계 틀

 struct person

 타입

 붕어빵

 man

 변수 (메모리를 차지)


  


atoi 함수 예제 소스 // a to i            ascii->int 문자열을 정수형으로 변환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h> #include <stdlib.h> //atoi함수를 사용하기 위한 헤더 int main() { char str[20]; printf("정수 입력: "); scanf("%s", str); printf("%d \n", atoi(str)); printf("실수 입력: "); scanf("%s", str); printf("%g \n", atof(str)); return 0; }


실수 15.0을 입력하면 정수 15로 출력된다.




typedef을 쓰는 두가지 이유 


typedef unsigned int     size_t;   // 범용의 효과 : int나 short만 바꿔도 모든 size_t의 type이 바뀐다.

typedef unsigned short  size_t;



축약의 효과 

typedef unsigned in uInt;    // ulnt





#include <stdio.h>

int main()
{
    int iNum1=1;
    char str[5];
    int iNum2=2;

    printf("iNum1 : %d \n", iNum1); 
    printf("iNum2 : %d \n", iNum2);

    printf("iNum1 address : %x \n", &iNum1); 
    printf("str address : %x \n", &str);
    printf("iNum2 address : %x \n", &iNum2);

    scanf("%s", str);

    printf("[%s]\n", str); // 문자열 값 그대로 출력 문자열 %s에는 []를 씌우는 것이 좋다. 
    printf("iNum1 : %d \n", iNum1);  // 
    printf("iNum2 : %d \n", iNum2);

    return 0;
}



Output:

1
2
3
4
5
6
7
8
iNum1 : 1 
iNum2 : 2 
iNum1 address : ff9066b0 
str address : ff9066b7 
iNum2 address : ff9066ac 
[]
iNum1 : 1 
iNum2 : 2 


지역변수와 메모리 Stack


가장 최근의 지역변수가 재사용할 확률이 높다.

메모리의 stack에는 일반적으로 값이 밑에서부터 위로 만들어진다.



넣어진 종이컵을 꺼내려면 나중에 넣은 종이컵부터 꺼내게 되는 것과 같다.


  1. iNum2    //  address : ff9066ac 
  2. str          // ff9066b7
  3. iNum1    // ff9066b0





fgets 함수

scanf와 gets는 입력할 수 있는 문자에 제한이 없기에 오버플로우에 취약하다.



가급적이면 fgets를 쓰는 것이 좋다. (int size : 입력받는 값을 제한)


 char *fgets(char *s, int size, FILE *stream);



fgets 예제소스


#include <stdio.h>

void ClearLineFromReadBuffer(void)
{
    while(getchar()!='\n');
}

int main(void)
{
    char perID[7];
    char name[10];

    fputs("주민번호 앞 6자리 입력: ", stdout);
    fgets(perID, sizeof(perID), stdin);
    ClearLineFromReadBuffer();      // 입력버퍼 비우기

    fputs("이름 입력: ", stdout);
    fgets(name, sizeof(name), stdin);

    printf("주민번호: %s\n", perID);
    printf("이름: %s\n", name);
    return 0;
}
       



Output :





'Study > C' 카테고리의 다른 글

c 복습-문제풀이2  (0) 2016.08.22
섭씨->화씨 변환, 최대 공약수 구하기  (0) 2016.05.03
2016-04-06-업무일지_포인터 및 함수  (0) 2016.04.06
20160405_포인터와 배열  (0) 2016.04.05
20160401_전역변수와 포인터  (0) 2016.04.04
728x90

배열


2차원에서 가로의 크기는 정해줘야 함






이중 포인터와 다중포인터



 PPP 

 PP

 P

  num A=100

 int***

  int**

 int*

  int


 



 대상의 type 

 자기자신의 type 

 int  

 (포인터)

     


 가리키는 대상

 포인터

 PP 

 *PPP

 

  **PPP

 B    

  ***PPP




 int * whoA[4]={&num1, &num2, &num3, &num4};  // 포인터 배열이고 16byte

 int (*whoB)[4]=arr2d;                                        // 배열 포인터이고 4byte


이중 포인터 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(void)
{
    double num = 3.14;
    double *ptr = &num;
    double **dptr = &ptr;
    double *ptr2;

    printf("%9p %9p \n", ptr, *dptr);
    printf("%9p %9p \n", num, **dptr);
    ptr2 = *dptr;
    *ptr2 = 10.99;
    printf("%9g %9g \n", num, **dptr);
 
    return 0;
}



Output:

1
2
3
0xffb30790 0xffb30790 
0x51eb851f 0x40091eb8 
    10.99     10.99 






포인터 변수에 const 선언 // const를 붙이면 해당 변수를 상수로 취급하게 된다.

#include <stdio.h>

int main()
{
    char *P1="TEST";
    const char *P2="TEST";
    char const *P3="TEST";
    char * const P4="TEST";
    const char * const P5="TEST";
    char const * const P6="TEST";

    printf("P1=[%s], [%p]\n", P1, P1);
    printf("P2=[%s], [%p]\n", P2, P2);
    printf("P3=[%s], [%p]\n", P3, P3);
    printf("P4=[%s], [%p]\n", P4, P4);
    printf("P5=[%s], [%p]\n", P5, P5);
    printf("P6=[%s], [%p]\n", P6, P6);

    printf(P1="zest\n");
    printf(P1="zest\n");
    printf(P1="zest\n");
   
    //printf(P4=zest);
    //printf(P5=zest);
    //printf(P6=zest);
    return 0;
}



리눅스에서는 주소가 모두 같게 나온다.

Output:

1
2
3
4
5
6
7
8
9
P1=[TEST], [0x8048698]
P2=[TEST], [0x8048698]
P3=[TEST], [0x8048698]
P4=[TEST], [0x8048698]
P5=[TEST], [0x8048698]
P6=[TEST], [0x8048698]
zest
zest
zest





메인 함수를 통한 인자 전달 // gcc 흉내내기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <stdio.h> int main(int argc, char *argv[]) // argc = 지정해준 명령행 인자의 개수 저장, argv = 문자열 배열 포인터 { int i=0; if(1==argc) { printf("gcc: fatal error: no input files \n"); return 0; } printf("전달 문자열 수: %d \n", argc); for(i=0; i<argc; i++) printf("%d번째 문자열: %s \n", i+1, argv[i]); return 0; }


전달된 문자열이 하나이므로 조건에 맞는 아래 문장이 출력된다.


Output:

1
gcc: fatal error: no input files 






EOF (End Of File) // 파일의 끝


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
    int ch;

    while(1)
    {
        ch=getchar(); 
        if(ch==EOF)  
            break;
        putchar(ch); 
    }
        return 0;
}


getchar를 통해 입력버퍼의 문자를 읽어들임

enter가 입력될때까지 키보드 입력값들을 계속해서 버퍼에 저장. enter가 파일의 끝이 된다.






fprintf 함수 //  특정한 스트림에 일련의 데이터를 특정한 형식에 맞추어 쓰게 된다.   리눅스 man 3 fprintf 참조

1
2
3
4
5
6
7
#include <stdio.h>

int main()
{
    fprintf(stdout, "test \n");
    return 0;
}


stdout(표준출력)을 통해 test라는 글자가 출력.

printf 함수가 실제로 출력하는 것이 없고 fprintf에 지시해서 출력하는 것이라고 할 수 있다.


Output:

1
test 


'Study > C' 카테고리의 다른 글

섭씨->화씨 변환, 최대 공약수 구하기  (0) 2016.05.03
2016-04-07-업무일지_구조체 및 함수  (0) 2016.04.07
20160405_포인터와 배열  (0) 2016.04.05
20160401_전역변수와 포인터  (0) 2016.04.04
20160329_C기초, 디버깅  (0) 2016.03.29
728x90

배열의 이름은 포인터이다.

int형 배열의 주소값 차는 4바이트이며, 주소값의 변경은 불가능하다. (값을 바꿀 수 없는 상수형)


포인터 변수와 배열의 이름 모두, 메모리의 주소값을 나타내고 저장한다.


1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
	int arr[3] = { 0, 1, 2 };
	printf("배열의 이름: %p \n", arr);
	printf("첫번째 요소: %p \n", &arr[0]);
	printf("두번째 요소: %p \n", &arr[1]);
	printf("세번째 요소: %p \n", &arr[2]);
	// arr = &arr[i];  // 이 문장은 컴파일 에러를 일으킨다.
	return 0;
}



Output:

1
2
3
4
배열의 이름: 0xff920370 
첫번째 요소: 0xff920370 
두번째 요소: 0xff920374 
세번째 요소: 0xff920378 


 


#include <stdio.h>

int main()
{
    char *cpStr="hello world \n";
    
  char caStr[20];
    printf("Hello world \n");
    printf(cpStr);

    caStr[0]='h';
    caStr[1]='e';
    caStr[2]='l';
    caStr[3]='l';
    caStr[4]='0';

    printf(caStr);
    putchar('\n');
    return 0;

}

castr의 배열에 저장된값 출력 배열의 경우 마지막에 null을 넣지 않으면 특수문자 \0 이 자동으로 붙음 그래서 castr[4]는 0을 넣음



임베디드

7F 45 4C // ELF파일임을 나타내는 아스키 코드







#include <stdio.h>

 int main(void) 
{
     char str1[] = "My String";
     char *str2 = "Your String";
     printf("%s %s \n", str1, str2);
     printf("str1 address : %p \n", str1);

     printf("main address", main);
     printf("str address", str2);

     printf("str2 address : %p \n", str2);
     str2 = "Our String";
     printf("%s %s \n", str1, str2);

     str1[0] = 'X';
     //str2[0] = 'X';
     printf("%s %s \n", str1, str2);
	    
     return 0;	
}




단순하게 화면을 출력할꺼면 포인터를 쓰는 것이 좋다.   // char *str2 = "";

위의 예제에서 포인터는 stack 영역에서 4byte를 차지하고 문자열은 10바이트를 차지한다. (M/y/_/S/t/r/i/n/g/null)



문자를 수정하려면 문자열을 쓴다.  // char str1[] = "";


메모리의 code영역은 Read only라 쓰면 안됨. (위의 소스에서 18행을 주석처리한 이유)

도스에서 허용하지만 리눅스에선 안되며 원래 쓰지 않는 것이 맞다.





포인터를 활용한 printf문

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main(void)
{
	char *cpStr = "A=%d \n";
	int A = 100;
	printf(cpStr, A);
	return 0;
}



Output:

1
A=100 



728x90

전역변수

 

어디서든 접근이 가능한 변수

전역변수와 지역변수의 이름을 달리하는 것이 좋다.

 



 

전역변수 아래와 같이 선언했을 때, 만들어진 파일의 용량이 엄청 커진다.

 

int A[1024*1024]={1, };

 

 


전역변수의 선언은 신중해야 한다.

프로그램이 복잡해지고 크기가 증가한다.

 

 

int A;

전역변수 A의 값은 0

 

 

 

 

지역변수에 static 선언하면?


: 전역변수의 성격을 지니게 됨


처음 1회만 초기화, 프로그램 종료시까지 메모리 상주(전역변수의 특성)

선언된 함수내에서만 접근 가능(지역변수의 특성)

 




전역변수에 static 선언하면?


분할 컴파일시, 파일간에 접근 불가능 (개별화됨)

 

 

 

// main.c 소스

#include <stdio.h>

int a;
int main(void)
{   
    printf("main: A = %d \n", a);
    test();
    printf("main: A = %d \n", a);
    return 0;
}

 

 

// test.c 소스

#include <stdio.h>

int a;
void test(void)
{
    printf("test : a = %d \n",a);
    a = 777;
    printf("test : a = %d \n",a);
    return;
}

 

 

 

test.c 소스 3행의 int a;에 static을 붙였을 때의 출력결과

 

 

 

 

 

 

비쥬얼 스튜디오 실습

 

 

위의 소스를 작성후 6행에 중단점 설정

 


주소를 고정하고 메모리의 값을 알기 위해 아래의 과정을 따라한다.


 

DYNAMIC BASE를 NO로 설정하면 주소가 고정된다.

 

디버그할 때 메모리의 내용보기

 

바로 위와 같이 설정하면 디버그시, 주소와 함께 메모리의 정보가 표시된다.


조사식에 &iNum을 넣으면 주소를 알 수 있고, 메모리란의 주소에 값을 넣으면 내용을 볼 수 있다. 

 

 

iNum의 주소 0x 00 19  fe  fc


메모리에 Little Endian 으로 fc  fe  19  00 이 올라가있음을 볼 수 있다.

 

 


포인터 변수의 크기

32bit system : 포인터 변수의 크기가 4byte

64bit system : 포인터 변수의 크기가 8byte




어셈블리 코드에서 dword ptr은 4byte pointer,

word ptr은 2byte pointer를 가리킨다.



 마찬가지로 포인터의 주소를 통해 값을 볼 수 있다. 



메모리의 TEXT 부분에 현재 실행중인 명령을 담고 있는 것이 Instruction Pointer이다.

EIP는 IP가 16비트에서 32비트 시스템으로 오면서 Extended 된것으로, 디버그시 EIP 레지스터도 확인 가능하다.





포인터 주소(0x 0019 FEF8)를 따라가서 메모리에 든 값 51EB 851F를 10진수로 바꿔보면, 

1,374,389,535라는 값이 나온다.


  

'Study > C' 카테고리의 다른 글

2016-04-06-업무일지_포인터 및 함수  (0) 2016.04.06
20160405_포인터와 배열  (0) 2016.04.05
20160329_C기초, 디버깅  (0) 2016.03.29
20160308_업무일지_그 밖의 기초 학습  (0) 2016.03.08
20160307_업무일지_파일 입출력  (0) 2016.03.07
728x90


프로그래밍 공부 과정

C → win32 API  →  C++  → MFC구조와 원리  →  MFC Application Programming

 

한빛

win32 API 정복

상 - 1~9챕터

 

 

오렌지미디어 열혈 C++

한빛 뇌를 자극하는 C++

 

한빛 Unix/Linux 필수 유틸리티

 

 

 

 

비쥬얼 스튜디오 실습

break 포인트를 지정해놓아야 디버그모드를 쓸 때 변수값이 어떻게 변하는지 알기 쉽다.

 

프로시져 단위 실행  (printf와 같은 함수 내부로 들어갈 수 있다)

전체한번에 수행 (f10)

 

ctrl+f5       디버그 하지않고 시작

shift+f5     디버그 모드 나가기

 

 

 

 

 

위와 같이 선택해서 프로젝트 파일 생성


옵션에서 줄 번호가 나오도록 수정 

 


디버그(프로그램상의 오류. 즉, 버그를 바로 잡는 것)를 할 때

f9 혹은 빨간 동그라미가 보이는 곳에 마우스 클릭을 해서 중단점을 설정할 수 있다. 


num값이 5가 되면 while문을 탈출하게 되는데, 중단점을 설정하게 되면 특정위치까지만 디버깅을 할 수 있게 된다.

  

 

아래 부분에 조사식에 num<5를 넣어 값과 참,거짓 여부를 알 수 있다. 



프로시저 단위실행을 했을 때, printf 함수내로 진입한 모습이다. 나가려면 프로시져 나가기를 누른다.


한단계식 코드 실행을 했을 때, 노란색 화살표로 진행지점과 도스창을 통한 출력여부를 확인가능하다. 


지역탭에서 위와 같이 각각의 값을 확인가능하다. result는 쓰레기값임을 알 수 있다. 


위의 소스에서도 조사식을 통해 값과 참, 거짓 여부를 디버깅하면서 볼 수 있다. 


 num1, num2가 더해지고 result 값에 5가 넣어진 걸 볼 수 있다.


printf 함수를 통해 도스창에도 위와 같이 사칙연산의 결과값이 나오고 값이 반환된다. (return 0;)

+ Recent posts