[TIL]20210629

박창현·2021년 6월 29일
0

TODAY I LEARNED

목록 보기
7/53

가상 클래스

가상 클래스는 미리 정의해놓은 상황에 적용되도록 약속된 보이지 않는 클래스.
우리가 직접 요소에 클래스를 선언하는 것은 아니고, 약속된 상황이 되면 브라우저 스스로 클래스를 적용해준다. css에서 :를 이용해 나타낸다.

예를 들어 특정 요소에 특정 클래스를 html단에서 지정하지 않고 뒤에 언급할 hover 클래스를 특정 액션값과 함께 css단에 주면 그 특정 요소위에 마우스를 가져가면 액션을 취하게 된다.

다양한 가상 클래스를 볼려면 하단의 링크를 참고.
https://developer.mozilla.org/ko/docs/Web/CSS/Pseudo-classes

문서 구조와 관련된 가상 클래스
:first-child : 첫 번째 자식 요소 선택
:last-child : 마지막 자식 요소 선택

li:first-child { color: red; }
li:last-child { color: blue; }
<ul>
    <li>HTML</li>
    <li>CSS</li>
    <li>JS</li>
</ul>

이렇게 하면 아래처럼 클래스가 보이진 않지만 가상으로 부여되면서 HTML과 JS에 각각 red와 blue가 적용된다.

<ul>
    <li class="first-child">HTML</li>
    <li>CSS</li>
    <li class="last-child">JS</li>
</ul>

앵커 요소와 관련된 가상 클래스
:link : 하이퍼 링크이면서 아직 방문하지 않은 앵커
:visited : 이미 방문한 하이퍼링크를 의미

사용자 동작과 관련된 가상 클래스
:focus: 현재 입력 초점을 가진 요소에 적용, focus(초점)는 지금 현재 선택을 받는 것을 의미. 예를 들면, 입력 폼 요소에 텍스트를 입력하려고 마우스 클릭해서 커서를 입력 폼 위에 올려놓으면 그때 입력 폼 요소가 초점을 받는 상태. 또 키보드의 탭 키를 이용해서 요소를 탐색하다 보면 링크나 버튼에 점선 테두리가 이동하는 것을 볼 수 있는데, 점선 테두리가 위치하는 것도 초점을 받은 상태이다.

:hover: 마우스 포인터가 있는 요소에 적용, 마우스 커서가 있는 요소에 적용됨. (마우스를 올렸을 때를 의미.)

:active: 사용자 입력으로 활성화된 요소에 적용, 현재 입력 초점을 가진 요소에 적용. 사용자 입력으로 활성화된 요소를 의미하는데, <a>를 클릭할 때 또는 <button>를 눌렀을 때처럼 순간적으로 활성화됨.

가상요소

가상 요소도 가상 클래스처럼 문서 내에 보이지 않지만, 미리 정의한 위치에 삽입되도록 약속이 되어있다.

다양한 가상요소를 볼려면 아래의 링크 참고.
https://developer.mozilla.org/ko/docs/Web/CSS/Pseudo-elements

:before : 가장 앞에 요소를 삽입
:after : 가장 뒤에 요소를 삽입
:first-line : 요소의 첫 번째 줄에 있는 텍스트, 모니터 가로 해상도에 따라 요소가 포함하는 내용이 변동된다.
:first-letter : 블록 레벨 요소의 첫 번째 문자

before와 after 가상 요소는 애초에 내용이 없는 상태로 생성되기 때문에 내용을 넣기 위해 content 속성을 이용해야 한다.

구체성

한 요소에 상반된 스타일이 입력된 경우 어느것을 우선시하여 작동시킬지를 명확하게 함.

구체성은 선택자를 얼마나 명시적으로(구체적으로) 선언했느냐를 수치화한 것으로, 구체성의 값이 왼쪽으로 더 치우칠 수록, 그리고 클수록 우선으로 적용이 된다.

0, 1, 0, 0 : 선택자에 있는 모든 id 속성값
0, 0, 1, 0 : 선택자에 있는 모든 class 속성값, 기타 속성, 가상 클래스
0, 0, 0, 1 : 선택자에 있는 모든 요소, 가상 요소
전체 선택자는 0, 0, 0, 0을 가진다. (즉, 구체성에 영향을 주지않음.)
조합자는 구체성에 영향을 주지 않는다. (>, + 등)

h1 { ... }  /* 0,0,0,1 */
body h1 { ... }  /* 0,0,0,2 */
.grape { ... }  /* 0,0,1,0 */
*.bright { ... }  /* 0,0,1,0 */
p.bright em.dark { ... }  /* 0,0,2,2 */
#page { ... }  /* 0,1,0,0 */
div#page { ... }  /* 0,1,0,1 */

인라인 스타일
인라인 스타일의 구체성 값은 1, 0, 0, 0이며 규칙들 중 가장 큰 구체성을 갖는다.

!important

important 키워드는 별도의 구체성 값은 없지만, 모든 구체성을 무시하고 우선권을 갖는다.
important 키워드는 속성값 뒤 한 칸 공백을 주고 느낌표 기호와 함께 사용.

상속

부모에게 제공된 스타일은 기본적으로 자식들에게도 다 상속된다.
단, margin, padding, background, border 등 박스 모델 속성들은 상속되지 않는다. 상속되는 속성들은 보통 상식적으로 구분할 수 있다. 예를 들어 테투리를 만드는 border 속성에게 부모에게 주어진 색상 값 등이 상속될 필요가 있을까? 이처럼 상식선에서 대부분 구분된다.

상속되는 속성의 구체성

* { color: red; }
h1#page { color: gray; }
<h1 id="page">Hello, <em>CSS</em></h1>

<em>에는 color: red가 적용되는데 그 이유는 상속된 속성은 아무런 구체성을 가지지 못하기 때문 이다. (심지어 0,0,0,0 도 아니다.)

캐스케이딩

스타일 규칙들을 모아서 중요도가 명시적으로 선언되었는지에 따라 분류합니다.
중요도가 명시적으로 선언된 규칙들은 그렇지 않은 규칙들보다 우선합니다.
중요도가 있는 규칙들끼리는 아래 다른 규칙들을 적용받습니다.
스타일 규칙들을 출처에 따라 분류합니다.
제작자 스타일 규칙이 사용자 에이전트 스타일 규칙보다 우선합니다.
스타일 규칙들을 구체성에 따라 분류합니다.
구체성이 높은 규칙들이 우선합니다.
스타일 규칙들을 선언 순서에 따라 분류합니다.
뒤에 선언된 규칙일수록 우선합니다.

<p id="bright">Hello, CSS</p>
p#bright { color: silver; } 
p { color: red; }

위의 경우에는 구체성에 따라 color: silver가 적용.

p { color: silver; }
p { color: red; }

위의 경우에는 선언 순서에 따라 color: red가 적용.

나중에 더 다양한 선택자를 알고싶다면 아래의 링크 참고.
CSS Selector Reference
https://www.w3schools.com/cssref/css_selectors.asp

C언어

선형 검색
정렬된 것과 상관 없이 맨앞부터 차례대로 확인

이진 검색
정렬되었을 때 중간을 열고 목표값보다 크면 오른쪽 작으면 왼쪽 이런식으로 탐색하는 방법

Big-O
알고리즘 실행시간의 상한선, 즉 최대 몇스텝안에 해결 가능하나

Big-Ω
알고리즘 실행시간의 하한선, 즉 최소 몇스텝안에 해결 가능하나

빅-오와 빅-오메가의 값 둘중 빅-오의 값이 적은 알고리즘이 더 좋은 알고리즘이다. 최악의 상황에서도 적은 스텝으로 문제해결이 되는 것이 좋은 알고리즘이라 생각할 수 있다.

여기서 O는 “on the order of”의 약자로, 쉽게 생각하면 “~만큼의 정도로 커지는” 것이라고 볼 수 있습니다.

O(n) 은 n만큼 커지는 것이므로 n이 늘어날수록 선형적으로 증가하게 됩니다. O(n/2)도 결국 n이 매우 커지면 1/2은 큰 의미가 없어지므로 O(n)이라고 볼 수 있다.

주로 아래 목록과 같은 Big O 표기가 실행 시간을 나타내기 위해 많이 사용됩니다.
O(n^2)
O(n log n)
O(n) - 선형 검색
O(log n) - 이진 검색
O(1)

예를 들어 선형 검색에서는 n개의 항목이 있을때 최대 n번의 검색을 해야 하므로 상한이 O(n)이 되지만 운이 좋다면 한 번만에 검색을 끝낼수도 있으므로 하한은 Ω(1)이 됩니다.

역시 아래 목록과 같은 Big Ω 표기가 많이 사용됩니다.
Ω(n^2)
Ω(n log n)
Ω(n) - 배열 안에 존재하는 값의 개수 세기
Ω(log n)
Ω(1) - 선형 검색, 이진 검색

c는 파이썬이나 자바와는 문자를 불리언 연산자로 대조하는 방법이 다르다.
파이썬의 경우 if ("abc"=="abc"): 으로 비교 할 수 있다면
c는 string.h를 불러오고 strcmp("abc", "abc")의 방법으로 풀어내야한다. 동일하면 0을, 왼쪽이 크면 -1, 오른쪽이 크면 1을 출력한다. 양옆을 비교할때는 각자리의 아스키 코드를 통해 비교한다. 이의 경우 정렬을 통해 비교하는 것이기 때문에 딱 한 글자만 비교할려면 %c로 받아서 비교한다면 == 불리언 연산자로도 비교가 가능해진다.

구조체

새로운 타입을 정의하여 만드는 구조체는 하나의 타입에 여러가지의 자료형을 담아야 할 때 사용할 수 있다.

typedef struct
{
    string name;
    string number;
}
person;

int main(void)
{
    person people[4];

    people[0].name = "EMMA";
    people[0].number = "617–555–0100";
    people[1].name = "RODRIGO";
    people[1].number = "617–555–0101";
    people[2].name = "BRIAN";
    people[2].number = "617–555–0102";
    people[3].name = "DAVID";
    people[3].number = "617–555–0103";
    
typedef struct 구조체이름 
{
    자료형 멤버이름;
} 구조체별칭;

이런 형태로 구조체 선언이 가능하다.

정렬

버블정렬: 정렬 알고리즘 중 하나는 버블 정렬입니다.

버블 정렬은 두 개의 인접한 자료 값을 비교하면서 위치를 교환하는 방식으로 정렬하는 방법을 말합니다.
버블 정렬은 단 두 개의 요소만 정렬해주는 좁은 범위의 정렬에 집중합니다.
이 접근법은 간단하지만 단 하나의 요소를 정렬하기 위해 너무 많이 교환하는 낭비가 발생할 수도 있습니다.
중첩 루프를 돌아야 하고, n개의 값이 주어졌을 때 각 루프는 각각 n-1번, n-2번 반복되므로 (n−1)∗(n−2)=n^2 −3n+2 번의 비교 및 교환이 필요합니다.
여기서 가장 크기가 큰 요소는 n^2 이므로 위와 같은 코드로 작성한 버블 정렬 실행 시간의 상한은 O(n^2)이라고 말할 수 있습니다.
정렬이 되어 있는지 여부에 관계 없이 루프를 돌며 비교를 해야 하므로 위와 같은 코드로 작성한 버블 정렬의 실행 시간의 하한도 여전히 Ω(n^2)이 됩니다.

선택정렬: 정렬을 위한 알고리즘 중 선택정렬을 배열 안의 자료 중 가장 작은 수(혹은 가장 큰 수)를 찾아 첫 번째 위치(혹은 가장 마지막 위치)의 수와 교환해주는 방식의 정렬입니다.

병합 정렬 (merge sort)
재귀를 이용해 병합 정렬은 원소가 한 개가 될 때까지 계속해서 반으로 나누다가 다시 합칠때 정렬하는 방식이다.
병합 정렬은 무조건 반으로 계속 쪼개고 정렬하기 때문에 O(n log n) 이면서 Ω(n log n) 이다. 위의 세가지 정렬 방법중 가장 빠른 것이 병합 정렬이다.

알아둘 것.!

알고리즘의 실행 시간의 상한을 비교하기 위해 Big-O 표기법 중 빠른 순서대로 올바르게 정렬한 것은 O(1) – O(log n) – O(n) – O(n^2) 이다.

병합 정렬, 선택 정렬, 버블 정렬의 실행시간의 하한을 빠른 순서대로 정렬한 것은 버블 정렬 - 병합 정렬 - 선택 정렬 이다.

4가지 알고리즘이 최선인 경우일 때의 실행시간이(하한) 빠른 순서대로 나열하면 이진 검색 - 선형 검색 - 버블 정렬 - 선택 정렬 순서 이다.

짤막한 상식으로 16진법에서 10을 읽을 때는 "일 영" 이라고 읽어야 한다. 또한 16진법을 표기할때는 앞에0x*(영.엑스)를 붙인다.

메모리주소, 포인터

C에서는 변수의 메모리상 주소를 받기 위해 &이라는 연산자를 사용. 그리고 서식문자로 %p (pointer) 를 이용한다,

#include <stdio.h>

int main(void)
{
    int n = 50;
    printf("%p\n", &n);
}

*를 사용하면 그 메모리 주소에 있는 실제 값을 얻는다.

#include <stdio.h>

int main(void)
{
   int n = 50;
   printf("%i\n", *&n);
}

말장난이지만 *&n 의 뜻을 풀이하자면 &n을 통해 n의 주소를 가져오고 *를 통해 주소에 담겨있는 실제 내용을 가져오기 때문에 50이라는 값을 얻을 수 있다.

#include <stdio.h>

int main(void)
{
  int n = 50;
  int *p = &n;
  printf("%p\n", p);
  printf("%i\n", *p);
}

int *p 에서 p앞의 *는 이 변수가 포인터라는 의미이고, int 는 이 포인터가 int 타입의 변수를 가리킨다는 의미이다. 쉽게 말하자면 int *까지를 한 묶음으로 보고 정수 n의 주소값을 p에 저장하는 변수 타입 이라고 생각하자.

첫번째 printf문은 포인터가 가르키는 n의 주소를 출력하고 두번째 printf문은 *가 들어가서 실제 값을 출력한다.

주소는 반드시 포인터에 저장해야한다 int형에 저장할 수 없다. --> int p가 아닌 int *p가 되어야한다는 소리.
현대의 컴퓨터에서는 포인터의 크기는 64bit, 8byte이다.

char *는 위와 비슷하게 int *처럼 문자의 주소값을 저장하는 변수 타입, 넓게 보면 string의 느낌이다. char *s="EMMA"; 이면 char s[5]="EMMA';와 같은 의미로 해석할 수 있다.

  char *name="emma";
  printf("%s\n",name);
  printf("%c\n",*name);  
  printf("%p\n",name);
  printf("%p\n",&name[0]);
  printf("%p\n",&name[1]);
  printf("%s\n",&name[2]);
  printf("%s\n",&name[3]);
  printf("%s\n",&name[4]);

의 출력값은

emma
e
0x400654
0x400654
0x400655
ma
a


이다.

그저 name을 형식지정자 %s로 출력한다면 종단문자(\n)이 나오기전까지 글자가 출력된다. 이것은 약속된 규칙이다.
%p로 출력한다면 시작되는 주소값을 출력한다.
이는 name[1]와 같은 값이다. 그리고 name[4]는 종단문자를 가짐으로 모든 비트가 0이라 빈칸이 출력된다.

  printf("%c\n",*(name+1));
  printf("%c\n",name[2]);

의 출력값은

m
m

이다.
첫째 줄을 해석하자면 name에는 포인터의 주소(첫글자의 주소인 0x400654)가 저장되어있는데 여기서 1을 더하면 두번째 글자의 주소를 가리키고, *는 주소내부의 값을 꺼내라는 것임으로 m이 나온다.
둘째 줄은 name의 두번째 배열값을 문자(%c)로 출력하라는 것임으로 m이 나온다.
이때 [ ] (대괄호) 는 컴퓨터과학에서는 구문 설탕이라 하는데, clang 컴파일러가 name[2]와같은 대괄호 표현식을 *(name+1)의 형태로 바꿔준다고 보면 된다.

typedef char *string;으로 미리 타입을 정의해주면 매번 char *을 쓰는 대신 stirng을 쓰면서 직관적으로 문자`"열"을 쓴다는 인식을 할 수 있다.

  char s[6]="EMMA";
  char t[6]="EMMA";
  
  printf("%p\n",s);
  printf("%p\n",t);
  printf("%c\n",*s);
  printf("%c\n",*t);


  if(s==t){
    printf("same\n");
  }
  else{
    printf("diff\n");
}
  if(*s==*t){
    printf("same\n");
  }
  else{
    printf("diff\n");
}

출력값

0x7fff72a7df96
0x7fff72a7df90
E
E
diff
same

이런 식으로 메모리안의 내용은 같지만 주소가 다르기 때문에 첫번째 if문에서는 diff가 나오고 메모리주소에 담긴 내용을 불러와서 비교하는 두번째 if문에서는 same이 나온다.

profile
개강했기에 가끔씩 업로드.

0개의 댓글