본문 바로가기

공부/타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js)

프론트엔드 기초: React + TypeScript(4)-포인터 변수

연산자

🔸정적인 데이터들을 유기적으로 행동하게 하여 새로운 가치를 창출해 내는 것

🔸예를 들어 학생들 과목 당 성적 데이터는 그 자체로는 의미가 없다.

🔸총점 및 평균을 데이터화 해야 그 의미가 있다.

산술연산자

🔸사칙연산이 기본

대입연산자

🔸오른쪽에 있는 값을 왼쪽에 대입하는 역할

증감연산자

증감 연산자 종류 증감 연산자 의미
전위 ++a a의 값을 1 증가시킨 후 연산을 진행
--a a의 값을 1 감소시킨 후 연산을 진행
후위 a++ 연산을 진행한 후 a의 값을 1 증가
a-- 연산을 진행한 후 a의 값을 1 감소

관계연산자

🔸두 개의 피연산자로 관계를 따지는 연산자로 같은지 다른지 어느쪽인지 큰지 작은지 비교하는 연산자

논리연산자

🔸두 개의 조건식을 결합하여 하나의 결과 값을 만들어낸다.

논리 연산자의 종류 논리 연산자의 의미
! 피연산자의 결과를 모두 반대로 만든다.
피연산자가 ture이면 false 리턴
피연산자가 false이면 true 리턴
&& 피연산자 모두 참이어야만 true 리턴
|| 피연산자 중 하나라도 참이면 true 리턴

분기문

조건이란?

🔸어떤 의미를 이루게 하거나 이루지 못하게 하기 윟하여 갖우어야 할 상태나 요소

if (조건) {
	내용
} else if (조건) {
	내용
} else {
	내용
}

 

💢이슈

내가 처음에 a == "y"를 비교하니

"comparison between pointer and integer"

에러가 나왔다.

== 는 정수간 비교라고 나왔다

js에서는 싱글이나 더블이나 모두 비교가 되는데..?

알아보니 " 쌍따옴표는 문자열이고 ' 작은따옴표는 단일문자라한다.

"y"는 문자열 리터럴이고 'y'는 문자 리터럴이라고 한다.

반복문

while문

🔸반복 조건을 만족하는 동안 반복 문장을 수행한다.

🔸반복 조건을 만족하지 않으면 while문을 빠져 나간다.

while (반복조건) {
	반복문장
}

 

while문 구구단 구현하기

 

사용자의 데이터 값을 받아 그 정수값까지의 합을 출력하는 코드 구현

 

배터리 충전 출력문제

이중 while문

*찍기

무한루프

🔸반복 수행이 무한이 일어나는 것

🔸반복 조건이 어느 시점에 무너질 수 있도록 설계

🔸무한 루프 안에서 어느 시점에 break나 return으로 빠져 나올 수 있어야한다.

for문

🔸for문은 while문과 다르게 변수의 초기화 연산과 증감 연산이 추가된다.

for(초기문; 조건문; 증감문) {
	반복내용
}

 

for문 구구단

break문과 continue문

🔸멈추거나 계속하거나

break

🔸반복문 내부에서 특정조건이 되어 break문을 만나게 되면 반복문을 빠져나간다.

continue

🔸반복문 내부에서 특정조건이 되어 continue문을 만나게 되면

그 이하의 수행은 무시하고 다시 반복의 시작점으로 간다.

함수

🔸함수는 나누어서 처리하기 위한 목적

  • 코드의 가독성 향상
  • 코드의 유지보수 및 확장용이

함수형 기반 언어의 동작구조

🔸대부분의 프로그래밍 언어는 함수의 집합체이다.

🔸함수들이 서로 연동하여 유기적으로 동작한다.

함수의 종류

표준함수

🔸언어에서 기본적으로 제공해주는 함수

🔸함수를 라이브러리화 시켜서 편리하게 사용할 수 있게 한다.

사용자 정의 함수

🔸사용자가 자신이 원하는 기능을 직접 만들 수 있다.

🔸표준 함수의 기능에는 한계가 있다.

🔸정형화된 완구와 가변적인 레고같은 완구의 차이

함수의 기본 형태

🔸데이터타입 : 함수가 리턴하는 값의 타입

🔸함수이름 : 함수 기능과 밀접한 이름으로 만드는 것이 좋음

🔸함수에 필요한 값을 전달할 때 사용

🔸중괄호 {} 사이의 영역 안에서 작성

인수 = 매개변수 = 전달인자 = 파라미터

자료형 함수이름 (인수목록) {
	함수의 내용
}

 

더하기 기능 함수 작성

 

함수의 호출과 프로그램 흐름

🔸함수 호출 및 반환되는 흐름을 순서대로 표현

void 타입

🔸결과값을 리턴하지 않는 함수

 

사각형의 너비와 높이를 곱해 넓이를 구하는 함수 정의

💢이슈

sq()함수를 변수 초기화와 함께 사용했더니

"void value not ignored as it ought to be" 오류가 났다.

반환할 게 없는 함수인데 변수에 넣으니 오류가 나는 것이라 함수만 호출해줬다.

 

사용자로부터 두 수를 입력받아 비교하여 최대값 최소값 구하는 함수 정의

변수의 범위

지역변수

🔸코드에서의 지역을 의미

🔸각 지역별로 같은 이름을 갖고 있더라도 다른 영역에 속해 있으므로 독립된 다른 변수이다.

🔸함수의 매개변수도 스택 메모리에 할당되는 지역변수이다.

🔸지역변수는 스택 메모리에 쌓이고 LIFO 형태로 소멸된다.

전역변수

🔸함수 바깥쪽에 선언된 변수

🔸프로그램이 시작하자마자 메로리 상에 올라가서 프로그램이 종료될 때 메모리 상에서 종료된다.

🔸스택, 힙이 아닌 데이터 영역에 저장된다.

static 변수

🔸지역변수처럼 중괄호 영역에서 선언되지만, 중괄호를 벗어나도 메모리 상에 고정되어 소멸하지 않는다.

🔸전역변수와 동일하게 데이터 영역에서 관리하기 때문에 프로그램이 종료될 때 메모리 상에서 종료된다.

🔸변수선언 앞에 static을 붙여서 static변수로 사용할 수 있다.

 

숫자를 누적해서 더하기 static 변수 사용하기

배열

배열의 개념

🔸배열이란 같은 속성을 가진 것들을 나열해 놓은 것

🔸배열은 요소가 순서대로 여러개 모인 것

🔸배열의 요소는 같은 속성을 지니고 있어야 한다.

 

배열이 왜 필요할까?

🔸배열이 없다면 정수형 변수를 하나하나씩 일일이 선언해줘야하는데

100개 1,000개가 필요해질 수 있다. 그에 따라 같은 형이라면 배열로 사용할 수 있다.

🔸많은 변수를 배열로 선언해서 사용하기 위해 필요함

int a[100];
int a[배열의 길이 선언];

배열의 선언 구조

🔸배열의 타입: 배열 요소들의 타입을 나타낸다.

🔸배열 이름: 각 배열 요소에 접근하기 위해 배열 이름을 나타낸다.

🔸변수의 개수를 나타낸다.

🔸배열의 첫 번째 인덱스는 무조건 0부터 시작

int array[3];
array[0] = 1; // 배열의 첫 번째 요소 접근
array[1] = 2; // 배열의 두 번째 요소 접근
array[2] = 3; // 배열의 세 번째 요소 접근

배열의 초기화

int array[5] = {1, 2, 3, 4, 5};

 

🔸배열의 길이 생략

🔸초기값의 갯수를 보고 컴파일러는 배열의 길이를 계산한다.

int array[] = {1, 3, 5, 7, 9};

배열의 복사

🔸같은 타입끼리 복사가 가능

🔸배열도 배열끼리 복사가 가능

🔸변수 복사하듯이 복사하면 에러가 발생한다.

💢error c2106에러: 배열은 상수이기 때문에 대입 연산자를 통해 값을 넘겨 받을 수 없다.

🔸배열은 요소끼리 복사해야 한다.

문자열 변수

🔸지금까지 우리가 사용했던 printf("Hello World")와 같은 문자열은 모두 상수

🔸문자열에 이름을 붙여주면 변수로 사용 가능

char str[12] = "Hello World";

🔸문자열을 세어보면 총 11개인데 11+1로 1개 더 설정하는 이유는

문자열 끝에 null문자가 반드시 추가되어야 하기 때문이다.

null 문자에 관하여

🔸문자열 끝에는 null 문자가 반드시 추가된다.

🔸null 문자가 왜 필요할까?

  • 컴퓨터가 문자열의 끝을 인식하기 위해 null을 표시한다.
  • 만약 변수길이를 100으로 선언하고 "Beautiful"의 문자열을 배열로 넣어준다면,
  • null을 포함한 총 길이 10을 제외하고는 모두 garbage로 채워져있다.
  • 그것 또한 문자로 되어있기 때문에 내가 입력한 문자열의 배열의 끝을 알기 위해
  • 마지막에 null로 마무리하여 끝을 인식한다.

🔸문자열 출력은 "%s"로 할 수 있다.

포인터

우리가 알고 있는 변수 선언 시 메모리 구조

🔸메모리는 주소를 통해 메모리에 접근하여 값을 읽고 쓸 수 있다.

🔸문자타입 1byte, 정수타입 4byte, 실수타입 8byte

포인터의 개념

🔸포인터는 포인터 변수의 줄임말로 메모리의 주소값을 저장하고 있는 변수이다.

🔸보통 주소값을 저장한다는 표현을 반대로 해당 메모리를 가리킨다고 표현한다.

🔸어느 특정 메모리 주소를 가리키거나 향하고 있다는 뜻이다.

포인터 사용방법

🔸포인터 변수 선언시 일반 변수명 앞에 * 기호만 붙여주면 된다.

🔸주소값만 저장하겠다는 의미이다.

✨사용방법

char *pA;
int *pB;
double *pC;

 

변수 선언시 일반 변수명 앞에 *기호 붙여서 포인터 변수 선언

int b = 100;
int *pB = &b;

우리가 scanf() 함수에서 사용한 주소값을 가르키는 & 기호를 사용하여,

포인터 변수 안에 저장할 수 있다.

💢만약 &가 빠져서 b 값만 할당된다면 에러가 난다.

🔥포인터 변수로 선언하는 기호는 변수명 앞의 * 이고
주소값을 찍는 출력타입은 %p 이고
포인터 변수 선언이 아닌 변수명 앞에서 사용하는 *는 가리키는 해당 메모리의 실제 값을 참조하라는 의미이다.🔥

예제의 메모리 구조

🔸변수 pB는 주소값 0x01을 저장하고 있는 포인터 변수

🔸이 주소값에 해당하는 메모리를 가진 변수는 int b

🔸pB는 변수 b의 주소 및 실제 값을 참조 가능

포인터와 배열

배열 이름의 의미

🔸배열의 이름은 해당 배열의 첫 번째 요소의 조소값을 갖는다.

즉, 첫 번째 요소의 주소값을 가리키는 포인터라는 의미이다.

int arr[5] = {1, 2, 3, 4, 5};

🔸arr은 이 배열을 가리키고 있는 포인터임을 알 수 있다.

🔸arr은 &arr[0]의 값과 일치한다.

 

예제코드를 통해 arr의 주소값은 &arr[0] 값과 같음이 확인된다.

배열 이름의 의미

🔸배열의 이름 == 포인터

🔸배열의 이름이 포인터이지만 일반 포인터와 결정적인 차이점이 있다.

🔸배열의 이름은 주소값을 갖는 포인터이지만 상수이므로 주소값을 변경할 수 없다.