c언어에서 가장 중요한 것은함수 그다음 구조체 이다.
c언어의 개요
- c라는 언어는 프로그래밍언어인데 그것은 컴퓨터랑 대화하기 위한 것
기계어는 너무어려워서 조금더 우리가 쉽게 이해할 수 있는 프로그래밍언어로 만든 것.
c언어를 기계어로 바꾸어주는 번역기(컴파일러(문법이맞는지도 검사))가 필요하다.
c언어- 절차식언어다(함수 중심의 언어) 함수들을 나열해놓고 순서대로 실행한다.
소스파일 작성> 컴파일해서 문법이맞으면 기계어로 변환하는데 이ㅏ떄 여러 가지 파일로 나누어짐 근데 링크를 해서 나누어진걸 모음. 그것이 exe파일이다.
----------------------------
프로그램 생성 작성을 건물로생각한다면
1) 건물생성 - 솔루션생성
2) 강의실생성 – 소스파일들을 생성
3) 사람추가 - 함수 생성
c언어에서 main은 꼭있어야한다.(프로그램의 시작점)
printf 함수를 선언 및 정의 해야하는데 그것은 어디에있는가?
b.c라는곳에 100개의 함수 정의가있다면
b.h에 100개의 함수의 선언을 넣는다.
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 value를 L value에 맞추는 것 ex)(int)a;
-암시적형변환(자동 형변환)
자기보다 큰(byte) 타입의 형으로는 형변환이된다 char>int로 char>short로 short>int로 .
프로그램에 연산에서 동일한타입의 연산에서는 동일한타입의 결과로 나온다 int/int = int
int로 계산시 1/10은 0.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바이트
전역정적공간에 저장.(상수문자열공간.)
상수문자열을 절대 값을 바꿀 수 없다.
즉 *를 문자열에 사용하면 상수테이블에 저장된다
-배열은 콜바이 벨류를 사용할 수없다...
배열과포인터가 주소가 같으면 서로 같이쓸 수 있다
문자열을 사용할떄는 값전달을 사용할 수 없다
9월 18일
이름 나이 성별 전화번호 저장.
9월 23일
다음주 수요일 시험본다아
int타입이 되면 얘도 된다.
구조체 – 사용자 정의 데이터 타입.
구조체 = 가방 :필요한 정보를 다 담아서 다님 > 필요에의해 가방은 전부 가지고다니던지
그안에 한가만 가질 수 있다.
맴버 = 가방의 소지품 하나하나
가방안에 가방을 넣을 수 있다 > 구조체 타입안에 구조체도 넣는 것 가능.
구조체 선언할때
struct phone myphone = {}; 이라고 하면
자료형은 struct phone 까지 이고
차수는 0차
변수이름은 myphone
구조체타입도 선언과 동시에 초기화가능....
0924
내가 가지고있으면 aaa.aa로하면되고
포인터를 써야하면 paaa->aa라고 해도딤.
ex) mem1.name은 char형이다!~!!!
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 |