연산자
정적인 데이터들을 유기적으로 행동하게 하여 새로운 가치를 창출해 내는것
- 산술 연산자 : 사칙 연산
- `+` `-` `*` `/` `%`
- 대입 연산자 : 오른쪽에 있는 값을 왼쪽에 대입하는 역할.
- 산술연산자와 혼용해서 사용할 수 있다.
- `=` `+=` `-=` `*=` `/=` `%=`
- 부호 연산자
- 증감 연산자
- `++a` `--a` : 값을 증감소 시킨 후 연산을 진행
- `a++` `a--` : 연산 진행 후 값을 증감소
#include <stdio.h>
int main()
{
int a = 5;
printf("%d",++a); // 6
printf("%d",a++); // 6
printf("%d",a); //7
return 0;
}
- 관계 연산자 : 두개의 피연산자의 관계에서, 같은지 다른지, 어느쪽이 큰지 작은지 비교하는 연산자
- `==` `!=` `>` `<` `>=` `<=`
- 논리 연산자 : 두개의 조건식 등을 결합하여 하나의 결과값을 만들어낸다
- `!` 결과를 반대로, `&&` 모두 true > true, `||` 하나만 true > true
- 비트 연산자
분기문
조건 : 어떤 의미를 이루게 하거나, 이루지 못하게 하기 위하여 갖추어야 할 상태나 요소
if문 : 만약에 ~ 라면
`if(수행조건){수행하고싶은일};`
수행조건에서 관계연산자를 사용해서 조건을 제한한다.
순서도 : 코드 동작순서를 flow chart 로 표현한다.
if ~ else if ~ else : 그 밖의
`if(수행조건1){수행조건1 만족시 수행} else if(수행조건2){수행조건2 만족시 수행} else {모든 수행조건들 불만족시 수행};`
반복문
반복적인 수행 while, for 문
while문
`while(반복조건){반복문장}`
반복조건을 만족하는 동안 반복문장을 수행하고,
반복조건을 만족하지 않으면, while문을 탈출한다.
탈출하는 조건을 필수로 제공해야 한다!
계산기
#include <stdio.h>
int main()
{
int i = 1;
int a;
scanf("%d",&a);
while(i<10){
printf("%d x %d = %d\n",a,i,a*i);
i++;
}
return 0;
}
//console
3
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
이중 while 문
구구단 2단부터 9단까지 > 반복 빈도가 2부분에서 발생하는 경우
`while(반복조건1){ while(반복조건2){반복문장} }`
안쪽 while 문이 더 많이, 자주 반복 돌게됨
구구단
#include <stdio.h>
int main()
{
int a=2;
while(a<10){
int i = 1;
while(i<10){
printf("%d x %d = %d\n",a,i,a*i);
i++;
}
a++;
}
return 0;
}
무한루프
반복 수행이 무한이 일어난다는것
`break` `return`으로 빠져나올 수 있어야 한다.
키보드 > OS > 프로그램(앱) > 데이터 출력
OS 안에서 무한루프를 돌면서 이벤트 감지하기. 특정시점에 빠져나갈 수 있도록! (창닫기, 장기간 움직임x 등)
for 문
변수의 초기화 연산과 증감 연산이 추가된다
`for (초기문; 조건문; 증감문) { 반복문};`
while 보다 조금 더 정돈된 상태
break, continue
break : 반복문 내부에서 특정 조건이 되면 break를 만나게 되는데, break 문은 while 문을 빠져나가게 된다.
continue : 이하의 수행은 무시하고, 다시 반복의 시작점으로 간다.
변수 - 지역, 전역, static
- 지역변수
- 같은 이름이라도, 다른 영역의 함수에 속해 있으므로 독립된 다른 변수로 처리한다.
- 스택 메모리에 순서대로, 다른 위치에 할당된다.
- 함수가 종료되는 순간에 스택 메모리에 저장된 변수는 소멸한다.
- 함수 호출 순서와 소멸 순서는 반대이다. FILO
- `함수의 매개변수`도 스택 메모리에 할당되는 지역변수이다.
- 전역변수
- 함수 바깥쪽에 선언된 함수이다.
- 모든 함수에서 사용할 수있다.
- 편리하지만, 유일성을 보장하기 어렵다.
- 코드관리의 어려움이 존재한다.
- 프로그램 시작하자마자 메모리 상에 올라가서 프로그램이 종료될때 메모리 상에서 소멸된다.
- > 스택 메모리가 아닌, 데이터 영역에 저장된다.
- static 변수 : 지역 + 전역
- 고정상태의 뜻
- 지역변수처럼 중괄호 영역에 선언되지만, 함수를 벗어나도 메모리 상에 고정되어 소멸하지 않는다.
- 프로그램 종료될때 소멸된다.
- 전역변수처럼 데이터 영역에 저장된다
배열
같은 속성을 가진 것들을 순서대로 나열해 놓은것이다.
배열을 사용하는 이유 ? 배열을 사용하면, 많이 간단하게 선언할 수 있다.
`int a[100]` 배열의 타입, 배열이름[배열길이]
4byte*배열길이 100 = 400byte 를 차지하는 배열이 된다.
[인덱스]로 배열에 접근할 수 있다. > 무조건 0부터 시작한다
배열도 초기화하는 과정 필요! > 배열의 길이를 생략하고, 초기값의 개수를 보고 컴파일러는 배열의 길이를 계산한다.
같은 타입끼리, 배열끼리 복사 가능하다
*배열은 상수이기 때문에 대입 연산자를 통해 값을 넘겨받을 수 없다. (변수처럼X) > JS는 가능
*인덱스(요소)끼리 복사해야한다. `arr2[i] = arr1[i]`
문자열에 이름을 붙여주면 변수로 사용 가능하다. `char str[12] = "Hello World";` > 문자열길이 + 1( \n null) = length
왜 문자열 끝에 null 문자가 반드시 추가되어야 할까 ? 빈공간에는 쓰레기값으로 채워져 있는데, 문자열 끝을 구분하기 위해 null로 표시한다. (컴퓨터는 문자와 쓰레기값을 구분하지 못하기 때문!)
포인터
객체지향 언어에서 많이 사용한다. Js의 Object 타입의 선언은 포인터를 사용한다?!
간접 참조 방법. `*` 주소값만 저장하겠다는 의미이다. 일반변수와 구분하기 위한 표기법 > `&`주소연산자
메모리의 주소값을 저장하고 있는 변수이다. 보통 해당 메모리를 가리킨다라고도 표현한다. 즉 어느 특정 메모리 주소를 가리키거나 향하고 있다는 뜻이다. 4byte 를 차지한다.
윈도우 원격 데스크톱 제어 기능 > 타 PC의 호스트 넘버를 적어주면, 사용할 수 있다.
`첫선언 *a` = &a > a값 = `첫선언 이후 *a`
포인터 + 배열
배열의 이름은 첫번째 요소의 주소값을 갖는다.
배열의 이름 == 포인터 상수 vs 일반 포인터 차이점?
배열의 이름은 `포인터 상수` 즉 상수이기 때문에 값을 변경할 수 없다.
함수와 포인터
함수에 인자를 전달하는 방법
- 값에 의한 복사 call by value
- 참조에 의한 복사 call by reference 주소값
메모리는 개별적으로 가지고 있고, 값만 복사된다.
배열형의 인자는 포인터형으로 받는다. 주소값만 복사 > 메모리 절감 효과
#include <stdio.h>
void func(int *pArr){
for(int i =0; i<5; i++){
printf("func의 배열 : %d\n",*(pArr+i));
}
}
int main()
{
int arr[] = {1,2,3,4,5};
func(arr);
for (int i=0; i<5; i++){
printf("%d\n", arr[i]);
}
return 0;
}
//console
func의 배열 : 1
func의 배열 : 2
func의 배열 : 3
func의 배열 : 4
func의 배열 : 5
1
2
3
4
5
☑️ 배운 점
static 변수에 대한 정확한 개념과 사용
배열은 상수이기 때문에 값을 인덱스로 각각 받아와야하고, 포인터 상수로 복사할 수 있다. 이때 포인터의 값을 변경할 수 없다.