4 분 소요

[CSS]background와 background-color의 차이

현재 내가 제작중인 블로그에서 옆에 사이드바[메뉴]를 제작중이다. 근데 계속 꼬리표 모양이 tiktok에 대해서는 깨진다.

이거 이슈를 해결하는 과정에서 스타일을 함수로 처리하는 것도 보았다. 예전에는 이런게 없었는데ㄷㄷ

HTML5까지 올라오면서 이것도 OOP를 조금씩 섞는게 아닌가 하는 생각을 잠깐 해보았다.(틀렸으면 말구~~)

[HTML]code insert

image-20231230144632511

위 이미지는 해당링크에서 참고한 코드이다. 이 코드를 이용해서 좌측상단에 시계를 만들어 넣으려고 한다.

그 결과는 다음과 같다.(나름 잘 된거 같다.)

image-20231230144731843

[콘솔로 만드는 애니메이션] 공의 자유낙하운동 구현

애니메이션의 기본은 정지영상을 연속적으로 표현하여 마치 움직이는 것처럼 보이게 하는 기법이다.

근데 우리 모두 알고 있듯이, C언어는 유니티처럼 애니메이션에 특화되어있지가 않다. 그래서 우리는 이미지를 다루지 않고, 대신 1)화면전환과 2)커서의 위치변화만을 다룰수밖에 없다는 결론이다. 이를 위해 연속적으로 화면을 지웠다가 보여주고를 반복하는데, 이때 화면을 지우기 전과 지우고 다시 보여준 후에 있어서 커서가 이동해 있어야 한다. 이해를 돕기 위해 우리는 공이 떨어졌다가 낙하위치의 절반까지 다시 튀어오르는 영상을 만들어보겠다.(출처)

코드를 구현해보면 다음과 같다.

#include <stdio.h>
#include <windows.h>

void gotoxy(int x, int y)
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

int main(void) {
    char ch1[3] = "●";
    int y, check = 24; //check - 처음 떨어질 위치

    do
    {
        for (y = 25 - check; y < 24; y++)
        {
            gotoxy(20, y);
            printf("%s", ch1);
            Sleep(50); //시간을 지연시키는 함수(공이 내려오는 시간조절)
            gotoxy(20, y);
            printf(" ");
        }
        check = (check - check / 2);
        
        for (y = 24; y > 24 - check; y -= 1)
        {
            gotoxy(20, y);
            printf("%s", ch1);
            Sleep(70);
            gotoxy(20, y);
            printf(" ");
        }

    } while (check != 1);
    printf("\n");
    
    return 0;
}

실행화면>

image-20231230154210231

코드 리뷰

아래 부분을 보면 배열 초기화에 있어서 3바이트로 설정한것을 볼 수 있다.

char ch1[3] = "●";

이때 여기서 “●”가 배열에 세개가 들어간 것이 아니다. 애초에 이 특수문자는 기계어상으로 보았을때, 총 3바이트를 차지하기 때문에, 적어도 3바이트의 공간을 확보해주어야 한다.

위 코드를 응용해보자(1)(feat.엘리베이터 구현하기)

위 코드를 이용해서 엘리베이터를 구현해보려고 한다.

일단 예전에 구현해보았던 건처럼 위 공에 해당하는 특수문자”●”가 위 아래로가 아닌 좌우로 이동하도록 한다.

gotoxy(20, y); -> gotoxy(y, 20);

엘리베이터에서 LED가 이동하는 것을 표현하는 거라서 좀더 확장시켜 보겠다.

gotoxy(y, 5);
printf("%s%s%s\n", ch1, ch1, ch1);
gotoxy(y, 6);
printf("%s%s%s\n", ch1, ch1, ch1);
gotoxy(y, 7);
printf("%s%s%s\n", ch1, ch1, ch1);
Sleep(70);
gotoxy(y, 5);
printf("   ");
gotoxy(y, 6);
printf("   ");
gotoxy(y, 7);
printf("   ");

그리고 현재 층을 출력하는 위치에는 다음과 같이 사용한다.

gotoxy(20, 10);
printf("현재 층:    \n", check); //floor_value initialization(overwrite)
gotoxy(20, 10);
printf("현재 층:  %d\n", check);

이제 이 두개를 함수화 시켜서 main함수를 다이어트시켜주자!(main부 간소화)

#include <stdio.h>
#include <windows.h>

char ch1[3] = "●";
int check = 24;

void gotoxy(int x, int y);
void lightControl(int y);
void getCurrentFloor(void);

int main(void) {
    
     //check - 처음 떨어질 위치
    int ws = 1;

    do
    {   
        //shiftRight(rise up)
        for (int y = 1; y < 36; y+=2)
        {
            lightControl(y);
        }
        check /= 2;  //12 - 6 - 3 - 2 - 1
        getCurrentFloor();
        
        //shiftRight(drop down)
        for (int y = 36; y > 0; y-=2)
        {
            lightControl(y);
        }

    } while (check != 1);
    printf("\n");
    
    return 0;
}

//Move cursor position
void gotoxy(int x, int y)
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

void lightControl(int y)
{
    gotoxy(y, 5);
    printf("%s%s%s\n", ch1, ch1, ch1);
    gotoxy(y, 6);
    printf("%s%s%s\n", ch1, ch1, ch1);
    gotoxy(y, 7);
    printf("%s%s%s\n", ch1, ch1, ch1);
    Sleep(70);
    gotoxy(y, 5);
    printf("   ");
    gotoxy(y, 6);
    printf("   ");
    gotoxy(y, 7);
    printf("   ");
}
void getCurrentFloor(void)
{
    gotoxy(20, 10);
    printf("현재 층:    \n", check); //floor_value initialization(overwrite)
    gotoxy(20, 10);
    printf("현재 층:  %d\n", check);
}

위 코드를 엘리베이터를 구현하기 위한 reference_code(1)로 두자.

위 코드를 응용해보자(2)(feat.엘리베이터 구현하기)

이번에는 다시 자유낙하 코드에서 값을 입력받는 부분을 두자. 그래서 30을 입력받으면 30에서 공이 떨어지게,

40을 입력하면 40의 위치에서 공이 떨어지게 하자!

(단, 입력값이 30 이상이어야 하고, 그렇지 않으면 다시 입력을 받도록 하자)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>

char ch1[3] = "●";
int check = 24;

void gotoxy(int x, int y)
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

int main(void) {
    int i;
    while (1)
    {
        gotoxy(0, 0);
        printf("                                                  ");
        gotoxy(0, 0);
        printf("30이상의 값을 입력해주세요.(이외에는 break) : ");
        
        scanf("%d", &i);
        if (i < 30) {
            printf("Break\n");
            Sleep(1000);
            break;
        }
        else 
        {
            do
            {
                for (int y = 25 - check; y < 24; y++)
                {
                    gotoxy(20, y);
                    printf("%s", ch1);
                    Sleep(50); //시간을 지연시키는 함수(공이 내려오는 시간조절)
                    gotoxy(20, y);
                    printf(" ");
                }
                check = (check - check / 2);

                for (int y = 24; y > 24 - check; y -= 1)
                {
                    gotoxy(20, y);
                    printf("%s", ch1);
                    Sleep(70);
                    gotoxy(20, y);
                    printf(" ");
                }

            } while (check != 1);
        }
    }
    return 0;
}

위와 같이 코드를 짰을때, 처음 한번은 제대로 동작이 되지만, 그 다음에는 동작이 제대로 되지 않았다. 뭔말이냐면,

처음에 30을 입력했을땐, 제대로 공이 왔다갔다하는 것을 확인했다. 하지만, 이후에는 다시 30을 입력하면 제대로 동작하지 않은 것을 확인했다.

image-20231230180612446

솔루션

원인은 바로 버퍼에 아직 30이 들어와 있고, 버퍼에 값이 빠져나가고 다시 값을 채워야 이에 대해 새롭게 상태의 변화를 인지해서, 공이 움직이는 동작을 수행하게 되는 것이다. 즉, 버퍼를 비우는 처리를 내가 해줘야 하는데, 그거 안해주고, 30을 무작정 넣으려니, 30이 버퍼에 안들어가고, 버퍼에서는 상태변화가 없으니, 위아래로 움직이지 않는 것이다. 고찰: 솔직히 C_lang에서 버퍼가 어떻게 동작하는 모르고 있었고, 애초에 컴파일러가 알아서 해주는 작업이라고 생각했다. 그래서 더 나아가 fflush()를 이용해서 버퍼를 비워야 하는지도 몰랐다. 고찰: 입출력을 할때 버퍼의 동작을 머릿속에 염두해두고 코딩을 하자!

temp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>

char ch1[3] = "●";
int check = 24;

void gotoxy(int x, int y)
{
    COORD Pos;
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos);
}

int main(void) {
    int i;
    while (1)
    {
        system("cls");

        gotoxy(0, 0);
        printf("                                                  ");
        gotoxy(0, 0);
        printf("30이상의 값을 입력해주세요.(이외에는 break) : ");
        
        scanf("%d", &i);
        if (i < 30) {
            printf("Break\n");
            Sleep(1000);
            break;
        }
        else 
        {
            do
            {
                for (int y = 25 - check; y < 24; y++)
                {
                    gotoxy(20, y);
                    printf("%s", ch1);
                    fflush(stdout);
                    Sleep(50); //시간을 지연시키는 함수(공이 내려오는 시간조절)
                    gotoxy(20, y);
                    printf(" ");
                }
                check = (check - check / 2);

                for (int y = 24; y > 24 - check; y -= 1)
                {
                    gotoxy(20, y);
                    printf("%s", ch1);
                    fflush(stdout);
                    Sleep(70);
                    gotoxy(20, y);
                    printf(" ");
                }

            } while (check != 1);
        }
    }
    return 0;
}

cf.2차원 배열을 동적으로 할당하는 방법

일반적인 방법을 여기를 참고하자.일단 stdlib.h 라는 헤더파일이 필요하다.

만약 행사이즈 20, 열사이즈 10의 배열을 만든다면 다음과 같이 구현할 수 있다.

int **t;
t = (int **)malloc(sizeof(int *)*20);
for(int i=0;i<10;i++)
    t[i] = (int *)malloc(sizeof(int)*10);

언어: , ,

카테고리:

업데이트:

댓글남기기