언어/C

C언어

하나의묵 2020. 3. 11. 12:54

 

c언어에서 가장 중요한 것은함수 그다음 구조체 이다.


c언어의 개요

 

- c라는 언어는 프로그래밍언어인데 그것은 컴퓨터랑 대화하기 위한 것

기계어는 너무어려워서 조금더 우리가 쉽게 이해할 수 있는 프로그래밍언어로 만든 것.

 

c언어를 기계어로 바꾸어주는 번역기(컴파일러(문법이맞는지도 검사))가 필요하다.

 

c언어- 절차식언어다(함수 중심의 언어) 함수들을 나열해놓고 순서대로 실행한다.

 

소스파일 작성> 컴파일해서 문법이맞으면 기계어로 변환하는데 이떄 여러 가지 파일로 나누어짐 근데 링크를 해서 나누어진걸 모음. 그것이 exe파일이다.

 

----------------------------

프로그램 생성 작성을 건물로생각한다면

1) 건물생성 - 솔루션생성

2) 강의실생성 소스파일들을 생성

3) 사람추가 - 함수 생성

 

 

 

 

c언어에서 main은 꼭있어야한다.(프로그램의 시작점)

 

printf 함수를 선언 및 정의 해야하는데 그것은 어디에있는가?

 

 

b.c라는곳에 100개의 함수 정의가있다면

b.h100개의 함수의 선언을 넣는다.

 

b.h의 선언들을 a.c에 복사하려면 include 라는 문법이다.

 

즉 헤더파일은 함수의 선언부를 가지고 있다,

 

 

 

 

 

 

 

 

 

기본데이터 타입.

 

프로그램은 크게 두가지 성질이있다 .(프로그램을 구성하는 두가지)

데이터 : 정보

함수 : 정보를 가공시키는 역할.

 

데이터는 두가지성질을 가지고 있다 type

-무엇을 ( 정수 ,문자 ,실수)

-얼만큼의 크기로 데이터를 저장할 것이냐?

-데이터 단위의 크기는 byte라는 개념을쓴다.

 

int num1; //변수의 선언.

num1 = 10; 대입연산.

 

대입연산 규칙 : R value , L value 서로의 타입은 일치해야한다.

함수안에서 선언한변수에 초기화를 안해주면 쓰레기값을 가지고있는다

 

 

%d //10진수 , %o // 8진수 , %x 16진수

 

데이터를 저장할 때 문자는 저장이 안됨. 내부적으로 숫자형태로 저장.

 

아스키코드 표에 있는 문자만 char형에 저장가능.

 

char 이 실제로 저장될때는 숫자로 저장하기 때문에 int형과 병행해서 사용가능하다.

 

 

-실수형 데이터 타입

&f, &lf(long float , double형을 출력할 때 사용)

정밀도 : 소수점 이하 몇자리까지 오차없이 정확한 표현이 가능한지를 나타낸다

 

실수형은 정수형을 포함한다.

 

 

 

 

 

 

 

 

(type)변환

:

 

-명시작 형변환(강제적 형변환): R valueL value에 맞추는 것 ex)(int)a;

 

-암시적형변환(자동 형변환)

자기보다 큰(byte) 타입의 형으로는 형변환이된다 char>intchar>shortshort>int.

 

프로그램에 연산에서 동일한타입의 연산에서는 동일한타입의 결과로 나온다 int/int = int

int로 계산시 1/100.1인데 프로그램에서는 0으로 값이나온다.

 

서로다른타입으로 연산하면 좀더 표현범위가 큰 것으로 결과값이 출력된다.

ex) float/int = float

 

 

상수 : 변수명앞에 const를 붙힌다. ex) const int num; num =10;//error

-상수는 절대로 L value에 올 수 없다. 최초에 초기화 한 것만 가질 수 있다.

-선언할 때 초기화를 해주지 않으면 쓰레기값을 계속 가지고있는다.

-상수는 보통 대문자로 표현한다 ( 아래에서 사용할 때 변수인지 상수인지를 구분하기 위해)

 

 

스트림?

- 수도꼭지 틀 때 파이프? ?? 즉 데이터의 흐름이다.

바이트(스트림의 기본 단위)들이 순서대로 입출력되는 논리적인 장치(순서가 바뀌지않음)

 

//출력스트림(프로그램에서 > 선택된대상으로 보내는 출력스트림)

fprintf(stdout, "hello world\n"); //여기서 stdout은 표준출력스트림(모니터)

즉 위에코드는 모니터로 hello world로 출력하라는 것.

 

getchar() //입력스트림

: 키보드로부터 입력받은 문자하나를 받아오는 것?

 

getchar 함수를 사용하면 버퍼를 감시하고있다가(비어있는지) 키보드에의해 버퍼에 문자가 쌓이고 엔터 입력되었을 때 첫 번째 입력한 문자를 가져가는데 문자하나만을 가져가기 때문에 abc이렇게 입력을 한다면 bc는 아직 버퍼에 남아있는 것이다.

 

putchar() //출력스트림

: 모니터로 문자하나가 전달됨

 

 

 

 

type

무엇을

얼마크기?

 

문자열은 왜 타입키워드가 안주어질까??

: 다른타입들은 적정량의 크기를 정해두면 그냥 쓸 수 있는데 문자열은 얼마만큼의 크기를

설정해두어야 하는지 모르기 때문이다!! (크기가 너무 가변적이다.)

 

문자열의 끝에는 반드시 NULL(\0)이 있다.(널까지 포함이다!! ab이면 ab\0까지 총 3바이트.)

문자열을 쓸 때 쓰고자하는 문자의 크기에 +1을 꼭해야한다~~~

 

-입력을받을때는 항상 버퍼에 엔터가 남게된다

 

gets() //입력

: 버퍼에서 문자를 읽어들이다가 엔터부분을 만나면 엔터를 널문자로 바꾸어서 프로그램에게 반환

즉 버퍼에서 엔터까지 전부다 싹비운다.

 

puts() //출력

 

 

문자열은 아스키코드와 상관없이 한글같은것도 저장한다.

 

공백문자 : 개행문자(엔터), , 빈칸(스페이스키)

 

scanf는 공백문자를 정보를 분리하는데 이용

 

 

scanf_s

: scanf 가 위험한이유는 문자나 문자열 탓이다. 기존 scanf는 크기가 초과하면 큰 일이벌어졌었음

_s는 문자열 타입 때문에 만들어졌다. 문자열을쓰는 입력기능은 뒤에 sizeof가 들어간다

 

scanf_s("%s", name, sizeof(name));

scanf_s(“%c”, &gender, sizeof(char)); // 문자나 문자열은 반드시 sizeof를 사용한다.

 

 

 

 

 

 

 

 

 

 

**********************************

데이터는 차수를가지고 있다.

 

- 변수를 선언할때 *,[]을 사용하면 차수가 하나올라간다.

- 변수를 사용할떄 *,[] 을사용하면 차수가 내려가고, &를 쓰면 차수가 올라간다.

 

0: 값의 의미를 가진다 //시작할 때 0.

1차이상 : 주소값의 의미를 가진다.

**********************************

 

 

 

//함수 구현 흐름

//1. 변수선언(데이터 생성)

//2. 변수의 초기화(상수값 대입 , 사용자입력)

//3. 연산을 통해 결과값 생성(연산자)

//4. 결과 출력

 

 

4일차

연산자

 

int a1 = 2, b1 = 3 , c1;

 

c1 = ++a1 + b1++ + a1++ + ++b1; //c1= 3+4+3+4

위처럼 계산할 때 전치를 먼저 베이스로 늘려주고 계산을 한후

 

아래코드에서처럼 하나하나 출력할떄 위에서늘려주지않은 후치를 늘려서 출력

printf("%d, %d ,%d", a1, b1, c1);

 

 

 

1 모든 숫자값들은 참과거짓을 가지고있는데 거짓은 딱하나 0뿐이다.

즉 마이너스던 플러스던 0을제외하면 다 참.

 

 

 

 

2주차

2-1 일차(제어문)

제어문 :if ,switch goto

 

반복문 : while, for, do while, continue & break

 

F9 : 브레이크 포인트

F5: 실행된는거 한줄씩보면서 실행하는 것을 실행

F10: F9에서 멈춘것부터 한줄씩 실행

 

프로그램의 핵심은 인풋과 아웃풋이다.

선언된 변수가 인풋변수인지 아웃풋 변수인지 먼저 생각해본다.

 

 

if문은 범위를 보거나 값을 비교하는 것을 둘다하는데

switch문은 값을 비교하는 것(정수타입, 캐릭터)에 많이쓰인다.

 

switch책갈피와같은 느낌.

 

go to는 예측이불가능해서 사용을 잘안함.//특별한 케이스에만 사용.

go to lable >lable로 이동해라.

 

 

반복문(초기값이 필요하고 , 조건식(종료조건), 증감식 필요.)

 

while (조건들이 흩어져있다) : 조건을 만족하면 문장실행 , 불만족이면 문장을 빠져나간다

do-while (먼저 문장을 실행하고 조건을 검사한다.)

 

for(조건들이 모아져있다)

 

 

 

 

- type => 변수/상수 생성(선언) <=배열!

입력 , = :초기화

연산자 => 결과값

결과 출력

 

 

 

 

배열?

한가지 데이터타입으로 이루어진 요소(저장소)의 모임.

 

배열의 선언

: 배열요소타입 배열명[배열의크기]

 

배열의 초기화(선언할 때 초기화)

: 중괄호{}

int arr[10]={1,2,3,4,5,6,7,8,9,10};

선언한 크기보다 초기화값이 조금있으면 나머지는 0으로 초기화된다.

 

int arr[]={1,2,3}; // 이렇게도 선언가능하다.

 

const int arr[10]={1,2,3,4,5}; 한번에 상수도 가능.

 

컴파일러는 인덱스가 유효한지 검사하지 않는다.

 

배열과 포인터는같다

 

 

 

일반적인 산술연산과 주소값의 연산은 다르다.(이동의 개념이 다르다)

------------------------------------------------------

 

 

- 저장공간은 값과 주소를 저장할 수 있다.

- 주소를 저장할 때 포인터라는 문법을 이용해 저장공간을 만들어야한다.

 

포인터 변수 선언

: int*n; //정수 변수의 주소를 저장하는 포인터변수

 

변수를 선언할떄 *,[] 을사용하면 차수가 올라간다

변수를 사용할떄 *,[].를 사용하면 차수가 내려간다

변수를 사용할떄 &를 쓰면 차수가 올라간다

 

0차는 값 이고 1차는 주소이다.

 

 

 

 

 

 

 

0차는 주소연산자&1차로 올릴 수 는있지만 2차로 올리지는 못한다.

 

 

배열포인터

함수포인터

void포인터

 

 

 

사용할떄 *p이런식으로 사용하는 것은 p라는 포인터가 가지고있는 주소로 가서 그곳의 공간이 가지고있는 값을 사용

 

주소 빼기 주소는 남는 값이 몇 개의 자료형값크기를 가지고있는지가 나온다

1012이라는 주소 1000이라면 12가남는데 이것은 3개의 int 형 크기이기 때문에 3이출력

 

 

-배열의 이름도 포인터(주소)이다.

-절대 배열의 이름([]없이 arr 이런식으로)L-value로 올 수 없다.

 

배열의 특정한주소를 포인터에 넣을 수 있고 그 포인터를 통해 배열에 접근가능하다

 

 

2차원배열 행과 열로 표현된 표의형태

 

int arr[2][3] = 2*3 6개의 공간이 만들어진다

여기서 1차원이동할떄는 4만큼이동이고 2차원이동(앞에[])를 이동할떄는 4*3=12 12만큼 주소를 이동한다.

 

2차원배열에서 [][]에서 뒤쪽 [](열의값)이 제일 중요하다..

 

-값끼리는 암시적변환이 가능하지만 포인터는 무조건 같은 자료형의 주소만 저장가능하다.

 

 

 

 

 

 

 

함수

 

함수는 나름대로 연산을 함.

 

 

 

 

 

함수 선언부에서 void 를쓰면 리턴할것이 없다.

반환형이 int 라는 것은 함수가 종료될 때 반드시 정수가 반환되어야한다.

 

 

! 함수란 모듈이다 (독립된 단위)(C언어의 핵심단위)

 

함수라는 것은 자기만의 고유한 기능을 가진다.

기능을 동작시키기 위해서는 데이터가 필요하다.> 함수가 뭔가를 처리하면 > 결과값이나옴

즉 함수는 매개변수를 받아서 연산을하고 결과값을 반환한다.

 

함수를 사용하는이유

재사용성.

산을보는 것이 아니라 하나하나의 기능을보고 함수화.(분활정복 접근법)

모듈화가 이루어진다.

 

 

함수를 사용하고 얻어와야하는 값이 2개이상이라면 포인터를 이용한다.

 

 

 

 

 

 

-추석이 끝나따...

// 09 16

 

정수값을 일차원배열에 저장.

 

흐름을 짠다 / 스켈레톤?

변수선언 + 초기화

기능 추가.

 

 

while(1)

{

저장정보

메뉴출력

선택

기능동작

}

 

 

 

 

 

문자열을 기본형 데이터타입으로 지원이 안된다.

무엇을 얼마만큼의 크기로가 명확하게 정의되기 힘들기 때문이다..

 

- 문자열이란 널문자로 끝나는 char타입 배열

 

 

문자열 4가지 방법

 

문자열 상수

- #define HELL “dadsdas” //이렇게 만들면되고 마지막에 자동으로 널문자가 넣어진다

메모리 공간내에 static storage class(전역정적공간)에 위치함 .

 

메모리구조

 

 

-----------

스택 //가장많이 사용되는 메모리 //함수와관련 //함수가 사라지면 사라져서?

전역정적 //전역변수 프로그램과 관련, 프로그램에 끝나면 사라짐,전역,정적,상수문자열,저장

코스 //함수가 저장되는 공간

-----------

 

함수안에서 변수선언하면 스택에

함수밖에 사용하면 전역정정메모리에 할당됨....

즉 지역변수는 선언된위치에 따라 결정되고

정적인지는 앞에 static붙으면 정적이다. 대신 전역인지 지역인지 상관없이 static이 붙으면 무조건 전역정적공간에 할당된다

 

 

2. 문자열배열

-반드시 저장할 개수보다 +1을 만들어야한다.

-문자열들은 무조건 1차원적으로 다루어진다.

 

 

3.문자열포인터

포인터변수는 무조건 4바이트

전역정적공간에 저장.(상수문자열공간.)

상수문자열을 절대 값을 바꿀 수 없다.

*를 문자열에 사용하면 상수테이블에 저장된다

 

 

-배열은 콜바이 벨류를 사용할 수없다...

 

배열과포인터가 주소가 같으면 서로 같이쓸 수 있다

 

문자열을 사용할떄는 값전달을 사용할 수 없다

 

 

 

918

 

이름 나이 성별 전화번호 저장.

 

 

923

다음주 수요일 시험본다아

 

int타입이 되면 얘도 된다.

 

구조체 사용자 정의 데이터 타입.

구조체 = 가방 :필요한 정보를 다 담아서 다님 > 필요에의해 가방은 전부 가지고다니던지

그안에 한가만 가질 수 있다.

 

맴버 = 가방의 소지품 하나하나

 

가방안에 가방을 넣을 수 있다 > 구조체 타입안에 구조체도 넣는 것 가능.

 

 

 

 

구조체 선언할때

 

struct phone myphone = {}; 이라고 하면

자료형은 struct phone 까지 이고

차수는 0

변수이름은 myphone

 

구조체타입도 선언과 동시에 초기화가능....

 

 

0924

 

내가 가지고있으면 aaa.aa로하면되고

포인터를 써야하면 paaa->aa라고 해도딤.

 

ex) mem1.namechar형이다!~!!!

 

 

0925

구조체 중첩

-가방안에 가방을 넣는 것과같음

그러므로 사용할 때 .을 두 번 사용해야한다.

 

내가가진 것이 값이면 .을쓰고 주소면 ->를 쓴다.

 

 

구조체 비트필드

 

비트 필드 : 구조체 맴버를 말함.(맴버의 저장단위가 비트)

목적 : 메모리의 효율적인 사용을 위해.

- 담을수 있는 타입이 제한됨 (대부분 unsigned int 사용)

- 각 맴버별로 비트단위를 나눌 수 있다

- : 숫자; 가있으면 구조체 비트필드이다.

 

원래 데이터의 기본적인 단위는 바이트

 

 

 

 

공용체 (union)

원룸을쓰는데 쉐어링을 하는데 시간을나누어서 한사람씩만 쓸수 있다.?

 

union mytype

{

int num1;

double num2;

} Mytype

//Mytype 변수는 한 개의 데이터 크기만 가지는데 int보다 double이 더 크기 때문에

double의 크기인 8바이트를 가진다.

 

 

열거형 (enum)

정수를 상수를 표현하는 기호 이름을 정의하는 것

-가독성 향상을 위해 사용

 

 

 

typedef

원래있는 타입에 새로운 이름을 붙이는 것.

int 자료형을 만약 size_t라고 바꾸고싶다면 > typedef int size_t 라고하면됨

 

 

명령행 인수

-정해진인수를 가질 수 있다

argc :명형행 문자열의개수 (공백으로 나뉜다?)

argv : 명령행 문자열 포인터의 배열

 

 

파일 I/O


- 중간이 끊어지지않는 바이트의 연속물이며 , 각바이트는 개개로읽어지는 것

 

 

파일종류

-텍스트파일

-2진파일(binary)

 

 

 

스트림- 흐름, 시작과끝이있는 것

 

stdin 입력스트림 키보드로부터 들어오는 상수값

stdout 아웃스트림 화면으로 출력

 

 

파일열고 닫기

 

 

파일열기

파일과 데이터를 주고받을 수 있는 스트림 생성

 

 

fopen() 파일을 연다

-성공적으로 열면 파일의포인터(첫번쨰 바이트를 가르키는 포인터)를 반환하고 열기를 실패하면 널포인터를 반환한다

파일명과 파일열기모드를 전달해야 사용가능.

read 모드인지 write 모드인지??

 

모드

- r : 텍스트파일 읽기 전용모드 , 파일이 이미있어야한다

 

- w : 파일의 쓰기전용모드 , 기존 동일한 이름의 파일이 존재하면 기존 데이터를 다지우고 새거를 생성 , 기존에 없으면 파일을 생성한다.

 

- a : 텍스트파일의 덧붙여쓰기 모드, 기존에 존재하면 파일의 끝에서 덧붙여씀, 없으면 파일생성(쓰기모드인데 w와 달리 기존의 파일에 데이터가 있어도 그걸 지우고 쓰는게 아니고 그 뒤에 덧붙여 쓴다)

 

r+ 을 쓰면 쓰기와 읽기를 둘다 가능하지만 하나의 파이프가 아니라 실제로는 두 개의 파이프가 만들어지는거다 (파일이 없으면 에러 )// 잘안씀.

 

 

 

파일닫기

-fclose() : 필요에따라서 버퍼를 플러시 한다(플러시란? :버퍼에서 파일로 밀어넣는거?)

 

 

 

 

 

파일의 끝 (EOF)

마이너스 1을 반환하면 EOF 파일의 마지막이다.!

 

 

파일IO포인터는 파일의 다음칸으로 자동으로 이동한다...

 

-파일에 저장시킨 바이트와 실제 바이트가 다른이유는 \n 는 윈도우에서 원래 \n만있는것이아니고 보이지않는 \r이라는 다음줄에 내려갔을때맨앞으로 땡겨주는 것이 포함되서 그렇다

 

 

2진입출력함수

 

 

 

 

'언어 > C' 카테고리의 다른 글

string cat, string lenth 구현..  (0) 2021.05.17
string reverse, 공백제거  (0) 2021.05.17
string 대소문자 변경  (0) 2021.05.17