저번에 만든 큐는 링크드 리스트를 활용한 큐인데, seq[5] 를 큐로 활용하는 것보다 오버헤드가 클 거 같은 느낌.
그래서 큐를 다시 만듦. 이번에 만든 큐는 환형 큐
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> typedef struct _TianQueue TianQueue; struct _TianQueue { int head; int tail; unsigned int count; char buf[5]; }; TianQueue *tian_queue_new () { TianQueue *q; q = malloc (sizeof (TianQueue)); q->head = 0; q->tail = 0; q->count = 0; return q; } void tian_queue_free (TianQueue *q) { free (q); } bool tian_queue_add (TianQueue *q, char c) { if (q->count == 5) return false; q->buf[q->tail] = c; if (++q->tail == 5) q->tail = 0; q->count++; return true; } bool tian_queue_remove (TianQueue *q) { if (!q->count) return false; if (++q->head == 5) q->head = 0; q->count--; return true; } char tian_queue_peek (TianQueue *q, unsigned int i) { if (!q->count) return -1; if (i < q->count) return q->buf[(q->head + i) % 5]; else return -1; } void tian_queue_print (TianQueue *q) { if (!q->count) return; for (int i = 0; i < q->count; i++) printf ("%c", tian_queue_peek (q, i)); printf (", head: %d, tail: %d\n", q->head, q->tail); } int main (int argc, char **argv) { TianQueue *queue; queue = tian_queue_new (); tian_queue_add (queue, '0'); tian_queue_add (queue, '1'); tian_queue_add (queue, '2'); tian_queue_add (queue, '3'); tian_queue_add (queue, '4'); tian_queue_print (queue); tian_queue_remove (queue); tian_queue_remove (queue); tian_queue_print (queue); tian_queue_add (queue, 'a'); tian_queue_add (queue, 'b'); tian_queue_remove (queue); tian_queue_remove (queue); tian_queue_add (queue, 'c'); tian_queue_add (queue, 'd'); tian_queue_print (queue); tian_queue_remove (queue); tian_queue_add (queue, 'e'); tian_queue_print (queue); tian_queue_free (queue); return 0; }그리고 ucs 를 utf-8 로 변환하는 거는
위키페디아에 잘 나와 있음.
c에 비트 연산을 활용하여 아래처럼 함수를 만듦
#include <stdio.h> #include <stdint.h> #include <string.h> #include <stdlib.h> char *tian_ucs_to_utf8 (uint32_t ucs) { if (ucs >= 0x00 && ucs <= 0x7f) { /* 1 byte */ char *utf8 = malloc (sizeof (char) * 2); utf8[0] = ucs; utf8[1] = 0; return utf8; } else if (ucs >= 0x0080 && ucs <= 0x07ff) { /* 2 byte */ char *utf8 = malloc (sizeof (char) * 3); utf8[0] = 192 + (ucs >> 6); utf8[1] = 128 + (ucs & (uint16_t) 63); utf8[2] = 0; return utf8; } else if (ucs >= 0x0800 && ucs <= 0xffff) { /* 3 byte */ char *utf8 = malloc (sizeof (char) * 4); utf8[0] = 224 + (ucs >> 12); utf8[1] = 128 + (ucs >> 6 & (uint16_t) 63); utf8[2] = 128 + (ucs & (uint16_t) 63); utf8[3] = 0; return utf8; } else if (ucs >= 0x10000 && ucs <= 0x10ffff) { /* 4 byte */ char *utf8 = malloc (sizeof (char) * 5); utf8[0] = 240 + (ucs >> 18); utf8[1] = 128 + (ucs >> 12 & (uint16_t) 63); utf8[2] = 128 + (ucs >> 6 & (uint16_t) 63); utf8[3] = 128 + (ucs & (uint32_t) 63); utf8[4] = 0; return utf8; } else { return NULL; } } int main (int argc, char **argv) { uint8_t ucs1 = 0x41; uint8_t ucs2 = 0x00a2; uint16_t ucs3 = 0xd55C; uint32_t ucs4 = 0x10348; char *utf8_1, *utf8_2, *utf8_3, *utf8_4; utf8_1 = tian_ucs_to_utf8 (ucs1); utf8_2 = tian_ucs_to_utf8 (ucs2); utf8_3 = tian_ucs_to_utf8 (ucs3); utf8_4 = tian_ucs_to_utf8 (ucs4); printf ("%s, %s, %s, %s\n", utf8_1, utf8_2, utf8_3, utf8_4); free (utf8_1); free (utf8_2); free (utf8_3); free (utf8_4); return 0; }이렇게 하여 포팅 준비는 모두 끝남.
else if는 순차적 비교 아닙니까? 조건문을 0xFFFFFF80 xor 하고선 0xFFFFF800 xor 하는 식으로 하면 되는 것 아니읍미까?
bit shift 연산은 한 싸이클에 같이하는 경우들도 있으니 0xFFFFFF80 으로 계속 비교하는데 ucs를 shift 해도 괜춘할 것 같읍미다?
아.. 순차비교 안 하고 한방에 작성하는 방법도 있구나, 위에는 malloc 으로 각 사이즈가 다른데, 5바이트 배열 받아서 그걸로 작업하면 더욱 빠르게 한 방에 가능할 듯요