break문
반복문 내부에서 특정 조건이 될경우 break를 하게 하면 반복문을 빠져나간다.
int main()
{
int a = 0;
while(1) {
if(a>100)
break;
printf("a의 값은 %d 입니다.\n", a);
a++;
}
printf("a는 100보다 크다\n");
}
//...
//a의 값은 99 입니다.
//a의 값은 100 입니다.
//a는 100보다 크다
continue 문
반복문에서 특정 조건이 되면 continue 문을 만나는데, continue 문 이하의 수행은 무시하고 반복문의 시작점으로 간다.
int main()
{
int a = 0;
while(a<100) {
a++;
if(a>80 && a<90){
continue;
}
printf("a는 %d\n", a);
}
}
//a는 79
//a는 80
//a는 90
//a는 91
함수
함수는 나누어서 처리하기 위한 목적
코드의 가독성 향상
코드의 유지 보수 빛 확장이 용이
- 표준함수: 언어에서 기본적으로 제공해주는 함수를 표준함수락 한다. 함수를 라이브러리화 시켜서 편리하게 사용할 수 있게 함.
- 사용자 정의 함수: 사용자가 직접 원하는 기능을 만듬.
함수의 기본 형태
- 데이터 타입
- 함수 이름
- 매개변수
- 함수 내용
int Add(int i, int j) {
return i+ j;
}
int main()
{
int a = 10;
int b = 20;
int sum;
sum = Add(a,b);
printf("합은 %d\n", sum);
return 0;
}
//합은 30
void 타입
결과값을 리턴하지 않는 함수. 타입스크립트에서도 사용된다.
변수의 범위
지역변수
한 함수(지역)에 속해있는 변수. 이름이 같아도 함수가 다르면 독립된 다른 변수이다. 지역변수는 해당 함수가 끝나는 순간 소멸된다. 지역변수는 스택 메모리에 저장되고 FILO 구조를 가진다. 매개변수도 스택 메모리에 할당되는 지역변수이다.
전역변수
함수 바깥쪽에 선언된 변수. 모든 함수에서 다 접근할 수 있다.
int global;
void Add(int i, int j) {
global = i+ j;
}
int main()
{
int a = 10;
int b = 20;
Add(a,b);
printf("합은 %d\n", global);
return 0;
}
//합은 30
return을 안써도 되서 편리해보이지만 전역변수는 위험성이 있다. 만약 코드가 복잡해지면 프로그램의 흐름을 파악하기 어려워진다. 디버깅도 어려워진다. 따라서 전역변수는 정말 필요한 경우에만 제한적으로 사용해야한다.
전역변수는 프로그램이 시작될 때 메모리에 올라가서 프로그램이 종료될 때 소멸된다. 전역변수는 스택 메모리가 아닌 데이터 영역에 저장된다.
static 변수
지역변수와 전역변수를 섞어놓은 듯한 변수. 지역변수 처럼 중괄호 영역에서 선언되지만, 중괄호를 벗어나도 메모리 상에서 소멸되지 않는다. 전역변수와 마찬가지로 데이터 영역에 저장된다. 생명주기도 전역변수와 동일하다.
int global;
void func(){
static int value =0;
value++;
printf("%d\n", value);
}
int main()
{
int i =0;
while(i<5) {
func();
i++;
}
return 0;
}
//1
//2
//3
//4
//5
총정리
지역변수는 함수와 생명주기를 같이 한다. static 변수는 선언 시점부터 프로그램이 끝날 때까지 살아있는다. 전역변수는 프로그램의 시작과 끝을 생명주기로 한다.
배열
같은 속성을 가진 것들을 나열해 놓은것.
배열을 사용하는 이유: 변수를 여러개 선언해야한다면 일일이 다 선언하기 보다는 배열을 이용해 간단하게 선언할 수 있다. 100개든 1000개든 간단하게 선언할 수 있다.
배열의 첫 번째 인덱스는 무조건 0부터 시작한다.
int main()
{
int total = 0;
int array[5] = {1,2,3,4,5};
total = array[0] + array[1] + array[2] + array[3] + array[4];
printf("%d\n", total);
return 0;
}
//15
배열의 초기화에서는 배열의 길이를 생략할 수 있다.
배열의 길이는 컴파일러가 알아서 계산한다.
int array[] = {1,3,4,5,6};
배열의 복사
같은 타입끼리 복사가 가능하다. 하지만 변수 복사하듯이 복사하면 에러가 발생한다.
int arr1[5] = {1,2,3,4,5};
int arr2[5];
arr2 = arr1;
//error C2106: 배열은 상수이기 때문에 대입 연산자를 통해 값을 넘겨 받을 수 없다.
배열은 요소끼리 복사해야한다.
int main()
{
int i;
int arr1[5] = {1,2,3,4,5};
int arr2[5];
for(i = 0; i<5; i++) {
arr2[i] = arr1[i];
}
for(i = 0; i<5; i++) {
printf("%d\n", arr2[i]);
}
return 0;
}
//1
//2
//3
//4
//5
문자열
지금까지 우리가 사용했던 문자열은 모두 상수였다. 문자열에 이름을 붙여주면 변수로 사용가능하다.
char str[12] = "Hello Wolrd";
문자열이 11개이지만 배열은 12개로 할당했는데 문자열의 끝에 null 문자가 추가되기 때문이다. 컴퓨터는 문자열이 어디에서 끝나는지 알 수 없기 때문에 마지막에 null 문자를 반드시 추가한다.
int main()
{
char str[12] = "Hello World";
printf("%s", str);
return 0;
}
// Hello World
포인터
변수 선언 시 메모리 구조. 메모리는 주소를 통해 메모리에 접근하여 값을 읽고 쓸 수 있다. 포인터는 포인터 변수의 줄임말로 메모리의 주소값을 저장하고 있는 변수이다. 주소값을 저장한다 == 해당 메모리를 가리킨다 라고 표현하기도 한다.
포인터 변수 선언시 일반 변수명 앞에 * 기호를 붙여준다. 주소값만 저장한다는 의미이다. & 기호를 통해 변수의 주소값을 얻어낼 수 있다.
int b = 100;
int *pB = &b;
포인터 예제
int main()
{
int b = 100;
int *pB = &b;
printf("b = %d\n", b);
printf("&b = %p\n", &b);
printf("pB = %p\n", pB);
printf("*pB = %d\n", *pB);
return 0;
}
//b = 100
//&b = 0x7fff4637444c
//pB = 0x7fff4637444c
//*pB = 100
선언시의 *는 이 변수가 포인터 변수라는 것을 표기하기 위함이고,
마지막의 *pB 는 가리키는 해당 메모리의 실제 값을 참조한다는 의미이다.
포인터와 배열
배열의 이름은 해당 배열의 첫번째 요소의 주소값을 갖는다. 즉 첫번째 요소의 주소값을 가리키는 포인터이다. arr 과 &arr[0] 의 값은 일치한다.
int main()
{
int arr[] = {1,2,3,4,5};
for(int i=0; i<5; i++){
printf("%d\n", arr[i]);
printf("%p\n", &arr[i]);
}
printf("배열의 이름 : %p\n", arr);
return 0;
}
코드를 돌려보면 arr 과 &arr[0] 의 값은 일치하는 것을 알 수 있다.
배열의 이름은 포인터 상수 이기 때문에 일반 포인터와 달리 주소값을 변경할 수 없다.
함수와 포인터
매개변수의 전달방식은 값에의한 복사와 참조에 의한 복사 두가지 종류가 있다.
함수의 매개변수가 너무 많아질 경우 난잡해보인다. 이럴 경우 배열을 전달인자로 사용할 수 있다. 배열은 포인터로 전달하고 받을 수 있다. 즉 주소값이 복사가 된다. 이를 참조에 의한 복사라고 한다.
void func(int *pArr){
for(int i = 0; i<5; i++) {
printf("함수 안의 배열 : %d\n", *(pArr + i));
}
}
int main()
{
int arr[] = {1,2,3,4,5};
for(int i=0; i<5; i++){
printf("%d\n", arr[i]);
}
func(arr);
return 0;
}
배열이 포인터 변수로 잘 전달되어 똑같은 값이 출력되는 것을 알 수 있다. *(pArr + i) 부분은 pArr[i] 로 바꾸어도 잘 동작한다.
이렇게 했을 경우의 장점은 무엇일까? 일단 메모리가 절약된다. 또한 일일이 복사하지 않아도 되서 성능적인 측면에서도 이득이 있다.
후기
오늘은 함수와 변수에 대해서 알아보았다. 또한 C언어의 중요 문법인 포인터, 그리고 배열에 대해서도 자세히 알아보았다.
키워드: 프로그래머스 데브코스, 국비지원교육, 코딩부트캠프
'프로그래머스 풀스택 데브코스 > 데브코스 TIL' 카테고리의 다른 글
웹 풀사이클 데브코스 TIL 47일차 (0) | 2024.01.26 |
---|---|
웹 풀사이클 데브코스 TIL 46일차 (0) | 2024.01.25 |
웹 풀사이클 데브코스 TIL 44일차 (0) | 2024.01.23 |
웹 풀사이클 데브코스 TIL 43일차 (0) | 2024.01.23 |
웹 풀사이클 데브코스 TIL 42일차 (0) | 2024.01.16 |