본문 바로가기

C

C언어 총 정리

728x90
반응형

c언어, web, system 크게 세 가지 분야로 배웠고 그 중 C언어에 대한 활동들 정리

글 속의 조사 과제 + 백준 등 여러 문제들을 깃허브 c언어 폴더에 워드 파일로 정리되어있음

<깃허브 링크>

https://github.com/MY-yeong/C

<C언어 -1>

1) C언어 소개

절차 지향 언어 VS 객제 지향 언어

2) 변수와 상수

3) 입출력

4) 연산자

5) 조건문

- 조사 과제

1 컴파일러에 대해 조사하기 (컴파일언어와 인터프리터언어(≠스크립트언어)의 차이점 조사)

2 디버그모드와 릴리즈모드의 차이 조사

3 리틀엔디안 vs 빅엔디안 조사 (0x41424344가 빅엔디안일 때 리틀엔디안으로는?)

4 c파일이 실행파일이 되기까지의 과정 조사

5 기계어와 어셈블리어에 대해 조사


<C언어 -2>

반복문

종류 - for문, while문, do~while문, go to문

출처: https://coding-factory.tistory.com/382

출처: https://www.happyfam.or.kr/ysoh/%EC%9E%90%EB%8F%99-%EC%A0%80%EC%9E%A5-%EB%AC%B8%EC%84%9C/

1) continue & break

2) while문

3) 다중 for문

4)switch 문

	switch(조건){
	case 조건:
		문장
	case 조건:
		문장
	default:
		문장
	}

 

- 조사 과제

1. do~while문 사용해서 구구단 만들기

2. goto문에 대해 조사하고, 간단한 예제 실습


<c언어 -3>

1) 함수

2) 함수의 구조

int main(void)

int main (void)

return type function name argument



return type: 함수가 반환할 자료형

function name: 함수의 이름

argument: 함수가 사용할 인자 (매개변수)

3) 함수의 선언과 호출

4) 지역변수와 전역변수

구분
일반 지역 변수
정적 지역 변수
전역 변수
정적 전역 변수
선언 위치
함수 안
함수 안
함수 밖
함수 밖
생성 시점
변수 선언 시
프로그램 시작 시
프로그램 시작 시
프로그램 시작 시
해제 시점
사용 범위
함수 리턴 시
함수 안
프로그램 종료 시
함수 안
프로그램 종료 시
프로그램 전체
프로그램 종료 시
선언된 소스 파일
초기화하지
않았을 때
쓰레기 값
(초기화 X)
0으로 초기화
0으로 초기화
0으로 초기화

5) 배열

같은 자료형의 변수들로 이루어진 '유한' 집합

배열을 구성하는 각각의 항목을 배열 요소라고 부름

배열의 위치를 가리키는 숫자인 인덱스는 1인 아닌 0부터 시작


int main() {
	int arr[5] = { 1,2,3,4,5 };
	int i = 0;
	for (int i = 0; i < 5; i++)
		printf("%x\n", &arr[i]);
}

 

int는 4바이트 할당, 4씩 증가

  • 다차원 배열

문자열 - 연속된 문자들의 모임

문자열의 끝에는 문자열의 끝을 표현하는 널 문자('\0')를 함께 보관해야함

※ 배열 사용시 주의사항

 
#include<stdio.h>

int main() {
	char str[9] = "minyeong";
	str = "kim-min"; //컴파일 에러
	//문자 배열에 다른 문자열을 대입할 수 없다.
}
  • 띄어쓰기가 있는 문자열을 입력해야 할 때 gets, fgets를 사용하는 방법도 있음
#include<stdio.h>

int main() { 
	char str[100];
	scanf("%s", str); //str에 공백(띄어쓰기 & 엔터가 있을 때까지 입력받음)
	scanf("%[^\n]", str); //띄어쓰기가 있는 문자열을 입력해야 할 때 사용 
	scanf("%100[^\n]", str); //\n가 입력될 때까지 100글자를 scanf 함
}

배열의 크기를 100으로 지정해놨지만 gets, scanf는 크기가 100넘게 입력 할 수도 있음

→ 버퍼 오버 플로우 발생 ! (나중에 system 영역에서 자세하게 다룰 예정)

scanf("%100[^\n]", str);

를 통해서 100자 제한을 걸어줌

- 조사 과제

1. 난수 관련 함수에 대해 조사 및 실습 (헤더가 무엇인지도 간단하게 같이 조사)

2 .call by reference & call by value 조사 및 구현

3 .main 함수의 argc, argv에 대해 조사 및 실습

4 .메모리 영역(code, data, bss, stack, heap)에 대해서 자세히 조사

5. static변수에 대해 조사 및 실습

6. Calling Convention: cdecl 와 stdcall 에 대해 조사

7. 버블 정렬에 대해 조사 (실습과제에 사용)


<c언어 -4>

1) 디버깅

▶ 프로그래밍 과정 중 발생하는 오류나 비정상적인 연산(버그)를 찾고 수정하는 것

디버그를 하는 행위 = 디버깅

※ visual studio 디버깅 방법

2) 문자열 함수

▶ 문자열을 다룰 때 사용되는 다양한 함수들

헤더) string.h / stdlib.h

함수) strlen / strcpy / strstr / strcat / strcmp 등

3) 재귀함수

▶ 자기 자신을 호출하는 함수

 

return 값이 있는 재귀함수

return 문은 함수에서 결괏값을 반환할 때 사용함

함수 정의 문에서 return 문이 사용되면 함수를 호출 했을 때 결과값(data)를 반환함

예제) 재귀함수를 이용해 !(팩토리얼)를 구하는 프로그램

#include<stdio.h>

int num = 1;
void number(int a) {
	num *= a;
	if (a == 0) {
		printf("1");
		return;
	}
	if (a == 1) {
		printf("%d", num);
		return;
	}
	number(a - 1);
}

int main() {
	int a;
	printf("INPUT NUMBER: ");
	scanf("%d", &a);
	number(a);

}

- 조사 과제 + 실습

1. memset, strlen, strcmp, strcat, strcpy, strrev, strtok, strstr, atoi, itoa 함수 조사 및 실습

2 . 위 문자열 함수 중 리눅스 환경에서 실행되지 않는 함수 조사


<c언어 -5>

1) 포인터

▶ 변수의 주소 값, 메모리의 주소를 저장하는 변수

포인터 변수는 다른 변수를 가리키는 변수

포인터를 이용하여 메모리의 내용에 직접 접근할 수 있음.

▶ 포인터 자료형의 크기

32bit - 4바이트, 64bit - 8바이트

& : 변수의 주소를 반환

* : 포인터가 가리키는 (주소의) 메모리 참조

  • 메모리 구조

변수는 메모리에 저장, 메모리는 바이트 단위로 액세스

#include<stdio.h>

int main() {
	int data = 10;
	int* ptr = NULL;
	ptr = &data;

	printf("data의 주소 : %p\n", &data);
	printf("data의 주소 : %p\n", ptr);

	printf("data의 값: %d\n", data);
	printf("data의 값: %d\n", *ptr);
}

2) 배열과 포인터

  • call by reference , call by value

▶ Call by reference (참조에 의한 호출)

함수에서 값을 전달하는 대신 주소값을 전달하는 방식

메모리에 대한 절감

▶ Call by value (값에 의한 호출)

함수에서 값을 복사해서 전달하는 방식

인자로 전달되는 변수를 함수의 매개변수에 복사함. 

원본 값을 바꿀 필요가 없는 경우에 사용함.

  • 다중 포인터
#include<stdio.h>

int main() {
	int num = 17;
	int* ptr = &num;
	int** ptr2 = &ptr;

	printf("before num: %d \n", num);
	(*ptr)++;
	printf("after num: %d \n", num);
	(**ptr2)++;
	printf("after2 num: %d \n", num);
}
 

※ 배열의 이름(변수명)은 배열의 시작 주소

&arr[1] = arr + 1 arr = &arr[0]

▶ 포인터 배열 vs 배열 포인터

 
#include<stdio.h>

int main(){
	int num = 10, num2 = 20, num3 = 30, num4 = 40;
	int arr[2][4] = { 1,2,3,4,5,6,7,8 };
	int i, j;

	int* ptr[4] = (&num, &num2, &num3, &num4); //포인터 배열
	int(*ptr2)[4] = arr; //배열 포인터

	for (i = 0; i < 2; i++) //포인터배열
		printf("%d", *ptr[i]);
	puts("");

	for (i = 0; i < 2; i++) { //배열 포인터
			for (j = 0; j < 4; j++)
				printf("%d", ptr2[i][j]);
			puts("");
		}
	}

3) 문자열 함수

▶ 문자열을 다룰 때 사용되는 다양한 함수들

- 조사 과제

1. math.h에 대해 조사한 후, math.h에 포함된 라이브러리 함수 조사 및 실습

2. 32bit vs 64bit 차이 자세하게 조사


<c언어 -6>

1) 매크로 함수

▶ define 전처리 지시자

전처리 : 컴파일 이전의 사전처리 과정, 코드를 컴파일하기 좋게 정돈하며 #이 달린 구문들을 처리함

#define : 프로그램 실행 내내 변하지 않는 상수나 문자열을 미리 정의하는 데에 사용

예제) 매크로 함수를 이용해 자연수 x 제곱 구하는 프로그램

#include<stdio.h>
#define nnu(a) (a)*(a)

int main() {

	int num = nnu(3 + 2);
	printf("%d", num);
	
}

2) 헤더파일

전처리기를 통해 다른 파일을 해당 파일에 포함시킴

▶ 헤더파일 포함 방법

#include <헤더파일명> //표준 라이브러리의 헤더 파일을 포함할 때 사용
#include "헤더파일명" //현재 소스 파일을 기준으로 헤더 파일을 포함

<상대경로>

“header.h”: 현재 소스파일과 같은 경로에 있는 header.h 파일을 포함

“test/header.h”: 현재 소스파일 경로에서 test 디렉토리 아래의 header.h를 포함

“../header.h”: 현재 소스파일 경로의 상위(이전) 디렉토리에 있는 header.h를 포함

<절대경로>

“c:/header/lib/header.h”: c:/header/lib/header.h경로에 존재하는 header.h를 포함

visual stuido 에서 헤더파일 생성 방법

- 조사 과제 + 실습

1. 상대 경로와 절대 경로 조사

2.[strcpy, strcat, strcmp, strstr, atoi] 함수를 포인터를 활용하여 직접 똑같이 구현하고, 헤더파일로 구현

(인자로 들어오는 문자열의 길이와 상관 없이 함수를 실행할 수 있어야한다.

string.h 헤더파일 사용 금지)


<c언어 -7>

1) 구조체

▶ 구조체 선언

구조체의 정의 & 선언 범위는 전역과 지역 모두 가능

struct 태그 {
     자료형 멤버1 ;
     자료형 멤버2 ;
}
 
#include<stdio.h>

struct Student {
	char Name[100];
	int age;
	int birth;
};

int main() {
	struct Student info = { "minyeong", 20, 30719 };
	printf("Name : %s \n", info.Name);
	printf("age : %d \n", info.age);
	printf("birth : %d \n", info.birth);
	info.age = 21;
	printf("Age : %d \n", info.age);
}
  • 배열과 같이 {}를 통해 초기화 가능
  • 접근 연산자 . 을 이용해 구조체 멤버에 접근
  •  

 

▶ 구조체 안의 구조체 선언

 
#include<stdio.h>

struct date {
	int year;
	int month;
};
struct Student {
	struct date Birthday;
	char Name[100];
	int age;
};

int main() {
	struct Student info = { {2003, 7}, "minyeong", 20 };
}

▶ 자료형 재정의

- typedef (기존 자료형) (새로 정의할 이름)

typedef는 이미 사용되는 자료형을 다른 새로운 자료형 이름으로 재정의할 수 있도록 하는 키워드

- 일반적으로 프로그램의 시스템간 호환성과 편의성을 위해 사용함 (가독성 ↑, 단순화)

▶ 구조체 포인터

접근 연산자 -> 를 사용

ptr -> Name = (*ptr).Name //같은 의미임

2) 동적할당

▶ 정적(static) 메모리 할당 방법

프로그램이 실행되기 이전에 변수의 저장공간 크기가 정해짐

프로그램 또는 함수가 시작되면 메모리에 할당하는 방식 . (DATA, BSS 영역, STACK 영역 사용)

▶ 동적(dynamic) 메모리 할당 방법

프로그램 실행 중에 필요한 메모리를 할당하는 방법 (HEAP 영역을 사용)

- 메모리를 효율적으로 사용할 수 있음 (할당 – 해제)

- 배열 할당 크기를 유동적으로 사용 가능

- 배열 사용 시 스택 메모리 부족으로 인한 오류를 해결할 수 있음

<메모리 관련 함수> 헤더파일 : stdlib.h

메모리
함수원형
기능
메모리 할당
void * malloc(size_t)
인자만큼 메모리 할당 후 기본 주소 반환
메모리 할당
void * calloc(size_t, size_t)
뒤 인자만큼의 메모리 크기로 앞 인자 수만큼 할당 후 기본 주소 반환
기존 메모리 변경
void * realloc(void *, size_t)
앞 인자의 메모리를 뒤 인자 크기로 변경 후,
기본 주소 반환
메모리 해제
void free(void *)
인자를 기본 주소로 갖는 메모리 해제

int* ip;

ip = (int*)malloc(sizeof(int) * 5);

→ int는 4바이트이니 (4 * 5 = 20) 20byte만큼 할당해준 주소


※ arr안에 주소(주소배열)이 들어감

arr 는 int 이중 포인터

malloc 에서 height 만큼 할당, height의 크기를 가지는 int 포인터 배열을 가리킴

반복문 arr[i] = int 배열 주소를 가지고 있음

int **array = int 배열의 주소들이 저장된 포인터 배열

이중 포인터 배열 → 포인터 배열 → 배열

#include<stdio.h>
#include<stdlib.h>

int main() {
	int i, num;
	char** str;
	scanf("%d", &num);
	str = (char**)malloc(num * sizeof(char*));
	for (i = 0; i < num; i++)
		str[i] = (char*)malloc(32 * sizeof(char));
	for (i = 0; i < num; i++)
		scanf("%s", str[i]);
	for (i = 0; i < num; i++)
		printf("%s\n", str[i]);
	for (i = 0; i < num; i++) //할당 입력
		free(str[i]);
	free(str); //할당 해제

}

- 조사 과제

1. calloc, realloc 조사하고 실습

2. 공용체(union)에 대해 조사 & 간단한 실습

3. 열거형(enum)에 대해 조사

4. Socket의 개념(종류, 역할, 용도 등 자세히)과 Socket 통신(TCP 프로토콜 통신)의 과정 조사

+ 구조체를 이용한 친구 관리 프로그램 제작

조건: 동적할당 사용 (구조체, 이름, 상태메시지) – 구조체 포인터는 동적할당 사용하지 않아도 괜찮음

각 기능을 함수로 만들기 – 친구 추가, 친구 삭제, 검색, 전체 출력

동명이인 있는 경우 예외처리 (입력 받지 못하게 하거나 에러 메시지 출력)

친구는 100명을 넘지 않는다. 이름은 영문이다.


<c언어 -8>

1) 파일 입출력

▶ 텍스트 파일 (text file)

- 메모장과 같은 편집기로 작성된 파일 등 (.txt)

▶ 바이너리 파일 (binary file)

- 동영상, 사진 파일, 실행프로그램 등 (.exe)

  • 스트림

입력과 출력에 대한 바이트들의 흐름

▶ 파일 입출력 스트림

 

스트림
설명
장치
stdin
표준 입력
키보드
stdout
표준 출력
화면
stderr
표준 에러
화면
stdprn
표준 프린터
프린터
stdaux
표준 보조
직렬포트

▶ 파일 open

FILE* fopen(const char* filename, const char* mode)

fopen()에서 char* mode 의 종류

+ 가 붙은 모드의 경우 읽기, 쓰기가 가능 / 그렇지 않은 경우 해당 모드 전용으로만 오픈

▶ 데이터 입.출력 모드

default 가 t 이므로 텍스트 모드로 불러울 경우 데이터 입출력 모드 적지 않아도 됨

▶ 파일 접근 처리

- 파일을 처음으로 열면 모드에 관계없이 파일 위치는 모두 0이다.

- 파일을 읽거나 쓰면 자동으로 파일 위치가 마지막으로 이동된다.

fseek()

ftell() : 파일 포인터의 현재 위치를 반환

rewind() : 파일 포인터의 현재 위치를 시작점으로 이동

파일 입출력 과정

▶ open 과 fopen

open() :

저수준, 버퍼를 사용 X

리턴값은 int형의 파일 디스크립터

파일 디스크립터는 커널에서 갖고있는 파일에 대한 번호

파일이 open되면 순서대로 번호가 3번 부터 붙음

파일을 읽고 쓸 때, read(), write()를 쓸 수 밖에 없음

fopen() :

고수준, 버퍼를 사용

파일 스트림 정보

리턴값은 FILE * 형태의 파일 스트림 포인터

fopen도 내부적으로 open을 쓰고, 파일 스트림 구조체에 저장하는 과정이 한번 더 이루어짐

파일을 읽고 쓸때, fread,fopen,fseek등 다양한 함수를 쓸 수 있음

- 조사 과제

1. 파일 디스크립터와 파일 포인터 개념과 차이점

2. 네트워크 포트 개념

3. TCP vs UDP

4. 검색을 통해 소켓통신 예시코드 완성, 코드 분석

(주석 꼼꼼하게 달기)

클라이언트, 서버 통신 실행 캡쳐

+netstat명령어 조사 후 사용하여 소켓통신 확인

+ 친구관리 프로그램 추가 기능 제작

*기능은 파일 입출력을 사용하여 구현*

저장(백업) 기능 (자동저장 or 저장기능 구현-자유, 하나의 텍스트파일에 모든 친구 정보 저장)

불러오기 기능 (저장된 학생 전체 정보 불러오기 후 목록으로 확인 가능하고 개별 삭제도 가능해야 함)

728x90
반응형

'C' 카테고리의 다른 글

main 함수의 argc, argv  (0) 2023.02.05
C 소켓  (0) 2022.11.26