보통 정해지지 않은 크기의 문자열을 저장할 때는 

1차원 메모리를 동적으로 할당 받아 사용합니다. 


이 메모리는 1차원 배열처럼 사용할 수 있지요.

다만, 할당받은 메모리의 위치를 벗어난 곳을 사용하면,

access 위반으로 프로그램이 동작하다가 강제 종료됩니다. (Run-time Error)

프로그래밍 하다보면 많이 발생되는 문제입니다. 

당연한 말이지만, 허가된 공간에서만 접근하고 사용해야합니다.


허가된 공간의 시작 주소는 string이며, 끝나는 지점(주소)은 string + STR_NUM입니다.

다만, 사용할 크기만큼 문자열을 넣어 사용하고 마지막 위치에 NULL을 넣어서

그 끝을 알릴 수 있습니다.


NULL 

 

 

다음처럼 5개의 공간을 할당 받더라도, 두개만 쓰고 3번째에 NULL을 넣어, 그 끝을 알릴 수 있습니다.





이젠

2차원 배열형태로 메모리 할당을 받은 경우를 설명하려 합니다


아래와 같이 1열엔 seoul, 2열엔 olympic, 3열엔 korea가 있고, 마지막열에 NULL로 그 끝을 알리려 합니다.

또한 각 행마다의 단어의 끝을 알리기 위해 seoul NULL, olympic NULL, korea NULL 로 저장합니다.


s

NULL 

 

 

 o

NULL 

 k

NULL 

 

 

 NULL

 

 

 

 

 

 

 


문자열의 경우 끝에 자동으로 NULL이 붙지만, 마지막 열은 일부로 NULL을 사용합니다. 


이 경우 print_strings함수에 단어의 갯수를 알려주지 않더라도, NULL이란 값이 보이면, 마지막 단어라는 점을 알릴 수 있습니다.

(물론 pring_stirng(char ** strs, int word_num) 이렇게 word_num을 직접 함수에 전달할 수 도 있지만요.)


print_strings함수에서는  NULL이 나오기 전까지 단어 출력을 반복합니다.( while(current[i]) )



다시 정리하면, 포인터의 사용시 마지막엔 NULL을 넣음으로...

허가 받지 않은 공간을 모르고 침범하는 오류를 피할 수 있습니다.


1차원 공간 뿐 만아니라 (문자열의 끝)

2차원 공간에서도, NULL을 사용할 수 있습니다. ( 마지막 단어)





Posted by 고무함지
,


오늘은 bit연산과 bit set 자료 구조에 대해 정리한 것을 올려봅니다.

어떤 상태정보를 저장하기 위해서 자료형을 선언해서 사용하는 방법은

C언어에서 당연한 방법이지만, 간단히 On Off 정보를 저장하기 위해서

char형 1byte, int형 4byte를 사용하는 것은 낭비입니다.


C++에서는 bitset class가 있어 이를 사용하면 되지만, 공부를 위해...

직접 만들어 봅니다. 제가 마이컴 코드를 배울 때는 대부분 이런 것들을

매크로로 만들어 사용하곤 했었는데요. 까먹기 전에 다시 정리해봅니다.


int LEDS 변수를 2진수로 하고 각 자릿 수가 LED0 ~ LED7의 on off상태를 

저장하는 것으로 구성한 코드입니다.

LEDS변수의 특정 자리를 OR 연산을 하면 특정 자릿수의 On을 설정할 수 있고,

LEDS변수의 특정 자리를 AND 연산을 하면, Off처리를 할 수 있습니다.


또한 아래의 if문장에서 처럼

And를 활용해서 bit의 상태를 확인할 수 있습니다.

i번째 자릿수의 bit가 on인지 off인지 확인하는 것이지요. 

" if(LEDS & (LED_ON << i)) "

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
 
enum { LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7 };
enum { LED_OFF, LED_ON };
 
void main() {
    int LEDS = 0
 
// LED1번과 LED7번을 켠다.
    LEDS |= LED_ON << LED1;
    LEDS |= LED_ON << LED7;
 
    for (int i = 0; i < 32; i++) {
        if (LEDS & (LED_ON << i))
            printf("LED#%d ON\n", i);
        else
            printf("LED#%d OFF\n", i);
    }
 
// LED1번을 끈다.
    LEDS &= ~(LED_ON << LED1);    
 
    for (int i = 0; i < 32; i++) {
        if (LEDS & (LED_ON << i))
            printf("LED#%d ON\n", i);
        else
            printf("LED#%d OFF\n", i);
    }
}
 
cs



위의 내용을 논리 회로 형식으로 그려보면 아래와 같이 설명할 수 있습니다.

OR연산을 통해서 1을 OR해주면 켠 것은 그대로고, 꺼진 것은 켜집니다.

AND연산을 통해서 0을 AND해주면 끈 것은 그대로고, 켜진 것은 끕니다.


위의 AND연산에서 아래의 식은 특정 bit가 ON(high) 인지 OFF(low)인지

확인하기 위한 방법으로 사용될 수 있습니다. 확인하고 싶은 bit에 1을 ANd하면 그

bit의 결과만 뽑아볼 수 있지요.


0 & 1 = 0

1 & 1 = 1 

Posted by 고무함지
,

C언어를 공부하는데, 무료로 사용할 만한 프로그램이 많습니다만...

저는 윈도우즈 PC사용자를 위한 무료 툴을 정리해보았습니다.

 

: free C Development SW : 

 

 

1. Turbo C

Turbo C같은 DOS상에서 동작하는 툴을 사용해도 됩니다. 

저는 오랜만에 추억을 되살리고자... 터보C를 다시 한번 깔아봤네요.

90년대 대학을 다닌 저로서는 이걸로 수업을 받았습니다... 진짜... ^^

 

무료로 다운 받을 수 있는 경로는 아래입니다. 

 

http://sourceforge.net/projects/turbocforwindows-9/?source=typ_redirect


 

 

 

 

2. GCC설치

Dos상에서 gcc를 사용하는 것이 더 좋을 것 같아서 아래의 링크의 설명을 바탕으로

gcc를 단순하면서도 간편하고 좋네요. 참고하세요.

http://holawang.blogspot.kr/2014/02/gcc-installing-gcc-at-windowsmingw-or.html

 

gcc설치하고, cmd 처서... 거기서 빌드하고, 편집은 메모장에서 하는 방식으로 하면 좋네요.

1) notepad test.c

2) 노트패트가 실행되면 거기서 코딩하고

3) commend창에서는 gcc -o test test.c 를 쳐서 빌드하고

4) test.exe를 실행해서 결과를 봅니다.

 

 

3. Tutorials point

웹 상에서 바로 프로그램 설치 없이 코딩과 컴파일 실행을 모두 해볼 수 있는 곳입니다.

아마도 물론 다양한 라이브러리를 제약 없이 쓰는 것들은 안될 것 같지만...... 

가볍게 C언어 기초 책을 보면서 따라 한다면, 이곳에 접속해서 공부하시는 것도 좋을 것 같습니다.

우선은 이 글을 읽으시면서, 한번도 프로그램을 설치해보지 않았다면, 먼저 방문해보세요.

 

투토리얼스 포인트: http://www.tutorialspoint.com/compile_c_online.php

          

추가로 집에 아이패드가 있는데, 아이패드에서 사파리 브라우저를 통해 이곳을 접근해서 코딩을 해도 문제 없이 되더라고요. 

실제 컴파일러가 아이패드에 올라온 것은 아닌 것 같고,

사이트의 서버에서, 빌드를 해주고, 그 결과만 text로 동적으로 보여주는 형식 같습니다.

 

 

4. 코드 블록 (code::Blocks)

 이건 최근에 안건데, 괜찮은 무료 IDE(통합개발 툴)이 많더군요. 그 중에서 하나 소개합니다.

이건 제가 직접 아직 써보지는 않아서, 세아슈님 블로그 포스팅을 여기에 소개합니다.

 

http://blog.naver.com/y007com/220146166293

 

 

5. Microsoft에서 Visual Studio 2015 무료 버전

 

마이크로소프트에서 드디어...... 무료로 visual studio를 배포하고 있습니다.

C언어 문법 공부용으로는 가장 좋은 것 같습니다. 인터페이스가 조금 복잡할 수 있지만,

컴파일을 하지 않아도, 실시간으로 문법체크를 하는 강력한 기능을 제공합니다.

엑셀이나, 워드 등에서 실시간으로 문법이 틀린 경우 빨간 밑줄을 자동으로 그려서 경고를 주는 것처럼

비주얼 스튜디오에서도 이러한 기능을 제공하고 있습니다.

 

https://www.visualstudio.com/ko-kr/products/visual-studio-community-vs.aspx 

Posted by 고무함지
,

링크드 리스트 자료구조에서 구현해야할 부분은 자료의 삽입, 삭제, 프린트입니다.

지난번에는 자료의 입력과 프린트만 구현했었는데, 이번엔

자료를 지우기, 자료를 특정 위치에 넣기, 자료의 순서를 반대로 하기 함수를 추가하도록 하는

코드를 올려봅니다.


그리고... 지난번에 소개한 글처럼 head node를 global값으로 사용한 방식이므로, 

아래 링크 : 링크드 리스트의 3가지 표현 방법 을 보시면, global값에서 지역 변수 등으로 사용하는 방법이 소개되니 참고하세요.

http://hamji.tistory.com/130


Null 포인터에 접근하지 않도록 하는 오류 방지 코드가 없이 기능만 구현하였기에, 참고 바랍니다.

안정성 있는 코드가 되려면, 오류 방지도 생각을 해야겠지요.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
 
typedef struct _Node {
    int data;
    struct _Node *next;
}Node;
 
Node *head;
 
void insert_node(int data, int n);
void delete_node(int n);
void insert_front(int data);
void insert_rear(int data);
void print_node(void);
void reverse_node(void);
 
void insert_node(int data, int n) {
    Node *node = malloc(sizeof(Node));
    node->data = data;
    node->next = NULL;
    
    if (n == 1) { // 맨앞에 넣기
        node->next = head;
        head = node;
        return;
    }
    Node *cur = head;
    
    for (int i = 0; i < n - 2; i++) {
        cur = cur->next;
    }
    node->next = cur->next;
    cur->next = node;
    return;
}
// 특정 위치에 값을 넣기 
void delete_node(int n){
    Node * cur = head;
 
    if (n == 1) {
        head = cur->next;
        free(cur);
        return;
    }
 
    for (int i = 0; i < n - 2; i++) {
        cur = cur->next;    
    }
    Node *temp = cur->next; 
    cur->next = cur->next->next;
    free(temp);
}
 // 맨 앞에 자료를 넣기
void insert_front(int data) {
    int n = 1;
    insert_node(data, n);
}
 // 맨 뒤에 자료를 넣기
void insert_rear(int data) {
    Node *node = malloc(sizeof(Node));
    node->next = NULL;
    node->data = data;
 
    Node *cur = head;
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = node;
}
 
void print_node(void) {
    Node*cur = head;
 
    for (int i = 0; cur != NULL; i++) {
        printf("[%2d]->", cur->data);
        cur = cur->next;
    }
    printf("\n");
}
 // 자료의 순서를 반대로 하기
void reverse_node(void) {
    Node *current, *prev, *next;
    current = head;
    prev = NULL;
    
    while (current != NULL) {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }
    head = prev;
}
 
void main(void) {
 
    insert_node(11);
    insert_node(22);
    insert_node(33);
    insert_node(44);
    print_node();
 
    insert_node(53);
    insert_node(62);
    insert_node(71);
    print_node();
    
    insert_rear(11);
    insert_rear(12);
    insert_rear(13);
    insert_rear(14);
    print_node();
 
    delete_node(1);
    delete_node(3);
    delete_node(5);
    print_node();
 
    reverse_node();
    print_node();
}
 
cs


Posted by 고무함지
,

 

변수나 함수의 사용시 특정 모듈이 아닌 프로그램을 구성하는 모든 모듈에서 한 전역 변수 / 전역 함수를 접근 할 수 있도록 지정자 (specifier)를 사용할 수 있고, extern을 사용해서 이 선언을 할 수 있습니다.

 

예를 들면 아래처럼 두 개의 파일이 각각 있습니다.

 

Main.c 파일

 

extern int value = 0;

 

Int main( void)

{

value = 3;

}

Ex.c 파일

 

void Print_data( void)

{

Printf("%d", value);

}

 

Main.c에서 선언된 value파일은 원래는 main.c 파일에서만 사용이 가능하지만, extern선언을 통해서 ex.c 파일에서도 사용이 가능하게 됩니다.

 

Posted by 고무함지
,