
C 언어 프로그래밍의 이해
프로젝트에서 C를 개발하게 되어 급하게 도서관에서 대여하여 읽어 보았습니다.
C는 대학교때 외에는 현업에서는 사용하지 않았는데요.
오랜만에 기본개념도 익힐 겸 가볍게 읽어 보았습니다.
- 출판사 : 한티미디어
- 출판일 : 2006
- 저자 : 안병호, 조국현, 최영근
Chap 3
기억장소 지정자
- auto : 보통 생략됨
- extern : 외부에서 사용된 전역변수 사용시
- static : 정적지역변수, 정적전역변수, 블록 밖에서 값이 유지됨
- resister
- 메모리 사용 안함, CPU의 rester에 저장됨
- &을 사용하여 주소값을 얻을 수 없음.
- rester 갯수가 허용치를 초과하면 자동으로 메모리를 사용함
- loop에서 사용시 효과적임
Chap 4
콤마 연산자
- x = (y=3, y+1);
- y=3 이 우선 실행됨
- y+1 의 결과가 x에 할당됨 (4)
*연산자
- 자료선언시 : '포인터' 변수임을 의미
- 실행문에서 : 해당 변수가 가르키는 장소의 '내용 or 값'
- 곱하기 연산자
Chap 5
. 연산자, -> 연산자
struct employee { char name[80]; float wage; } emp
struct employee *p = &emp;
emp.wage = 123.45;
p->wage = 123.45;
if문
- 참 : 음수를 포함하여 0이 아닌값
- 거짓 : 0
Chap 6 함수의 기본
함수원형
- 함수 원형 (prototype) / 함수 호출 / 함수 정의
- 함수 원형은 type check를 위해 ANSI C 표준에 추가됨. 없어도 오류가 생기지는 않음
- 함수 원형 예제
void a(int i); // 파라메터 int 형
void a(void); // 파라메터 없음인자와 매개변수
f(3); // 3은 인자
int f(int x) { .. } // x는 매개변수- 인자 : argument
- 매개변수 : parameter
난수발생
int num = rand() % 6 + 1; // 1~6 사이의 정수Chap 7
main()
void main(int argc, char *argv[] { ...}- argc : argument count
- argv : argument value
가변 매개변수
func(int a, int b, ...) { .. } // 매개변수에 점 3개는 가변을 의미함컴파일 분리
- 소스파일을 분리하여 컴파일함. h에 함수 원형 등을 선언하고 h 파일을 include
- pgm.h
# include
# define
함수 원형
typedef
구조체 선언- main.c
# include pgm.h
int main() { ... }- prn.c
# include pgm.h
...Chap 8. 배열
2차원 배열
int d[10][20]; // 2차원 배열 선언
d[1][2]; // 1행 2열 값에 접근. 메모리 크기는 10*20*sizeof(int)함수의 배열 전달
void main(void) {
int i[10];
func1(i);
...
}- 포인터로 전달시 : void func1(int *x) { ... }
- 해당크기 배열로 전달시 : void func1(int x[10]) { ... }
- 크기없는 배열로 전달시 : void func1(int x[]) { ... }
배열의 초기화
int i[10] = {1,2,3,4,5,6,7,8,9,10};
char str[9] = "I like C";
char str[9] = { 'I', ' ', 'l','i','k','e',' ','C',''}; // "I like C"돠 같음
int sqrs[][2] = { 1,1, 2,4, 3,9, 4,16};문자열 처리함수
#include<string.h>
strcpy(s1, s2); // s2를 s1으로 복사
strcat(s1, s2); // 연결
strlen(s1); // s1의 길이
strcmp(s1, s2); // s1과 s2가 같으면 1, s1>s2 이면 0이상, s1<s2이면 0이하
strchr(s1, ch); // s1에서 첫번재 ch 포인터
strstr(s1, s2); // s1에서 첫번째 s2 포인터chap 9
포인터 연산
p가 정수형(2byte) 포인터이고, 현재 2000 번지를 가르킬때
- p++ : 2002번지
- p-- : 1998번지
- p=p+12 : 2012번지
- *연산자 및 /연산자는 사용할 수 없음
chap 10
문자열과 포인터
// 문자열 초기화
char *p = "hello world";
//배열의 포인터
int sample[10]; // --> sample = &sample[0];
// 포인터와 배열
char str[80], *p1;
p1=str; // --> str[4] = *(p1+4);
// 문자열과 포인터 #1
char *p_word = "abc";
char word[] = "abc";
printf("%s", p_word);
printf("%s", word);
// 문자열과 포인터 #2
char *p_word = "abc";
p_word = "def"; // 정상 (p_word는 포인터 "변수"이므로)
char word[] = "abc";
word = "def"; // 오류 (배열이름(word)는 "상수형"이므로)다중 간접 참조
float **balance; // "실수형 포인터"에 대한 포인터
int main(void) {
int x, *p, **q;
x=10;
p=&x;
q = &p;
printf("%d", *p); // 10
printf("%d", **q); // 10
printf("%d", p); // 1234567
printf("%d", *q); // 1234567
}
x p q
+--------+ +--------+ +---------+
| 10 | <--------+ &x | <--------+ &p |
+----+---+ +--------+ +----+----+
^ |
+---------------------------------------+
**q
함수 포인터
- 파서, 인터프리터, 수학연산, 입출력연산 등의 개발시
- 함수를 나열하는 switch를 사용하지 않고 함수 포인터의 배열을 사용한다.
동적 할당
int *dp;
dp = malloc(50*sizeof(int)); // 50개의 정수를 저장하기 위한 공간을 할당, 실패시 nullchap 11. 구조체
구조체
// 구조체 선언
struct addr { // addr은 태그
char name[30];
char street[40];
int zip;
} addr_info // addr_info는 구조체 변수, 태그와 구조체변수 중 하나는 생략 가능
// 멤버접근
addr_info.zip = 1234;
// 구조체 포인터
struct employee {
struct addr address;
int age;
} *list;
list->name="kimstar";
list->age=20;
printf("%d", list->age);
// 중첩된 구조체 (최대 15개까지 가능)
struct emp {
struct addr address;
float wage;
} worker;
worker.address.zip = 1234;
// 비트 필드 #1
struct status_type {
unsigned delta_cts : 1; // int, unsigned, signed만 사용가능, 1bit
unsigned ring : 1;
} status;
status.ring = 0;
// 비트 필드 #2
struct emp {
struct addr address;
float pay;
unsigned lay_off : 1; // 고용인 상태
};공용체 (Union)
union u_type {
int i;
char ch;
}
i
+-------------------+
+---------+---------+
| | |
+---------+---------+
+---------+
ch
// 같은 메모리 장소를 i와 ch가 공유
// 특별한 형변환 필요할 경우 사용
나열형
enum coin { penny, nickel, dime=100, quarter } // penny=0, nickel=1, dime=100, quarter=101
enum coin money;
money = dime;
if(money==quarter) printf("quarter");
switch(money) {
case penny : printf("penny"); break;
}구조체 크기
struct s { char ch; int i; float f; } s_var;
// 구조체 크기는 1+2+4=7byte ??
// 단락(paragraph)는 16byte일때, 단락으로 구조체를 할당한다.
// 정확한 크기는 sizeof로 확인해야 한다.
union u { char ch; int i; float f; } u_var;
// 가장큰 float 크기로 결정된다. 따라서 4byte typedef
자료형 이름을 재정의하여 이해도를 높여줌
typeof float balance;
balance over_due;chap 13. 선행처리기
선행처리기
// 일반적으로 대문자를 사용
#define TRUE 1
#define FALSE 0
#define E_MS "standard error on inputn"
// 함수와 유사한 매크로
#define ABS(a) (a)<0 ? -(a) : (a)
// 차이점
#include <stdio.h> // 시스템 정의 파일
#include "stdio.h" // 사용자 정의 파일, 현재 디렉토리에서 찾음
// 조건부 컴파일 지시자 : #if, #else, #elif, #endif
// 조건부 컴파일 지시자 : #if
#define MAX 100
#if MAX>99
printf("~~~");
#endif
// 조건부 컴파일 지시자 : MYFILE이 정의되었는지 검사함
#if defined MYFILE
printf("~~~");
#endif
// 조건부 컴파일 지시자 : DEBUG 정의되지 않았을때만 동작
#if !defined DEBUG
printf("~~~");
#endif
// 조건부 컴파일 지시자 : #error, #undef, #line, #pragma
#error this is an error message // 오류시 이 문구가 추가됨
#define LEN 100 // LEN은 100으로 정의
#undef LEN // LEN의 정의가 해제됨
__LINE__ // 소스코드의 줄번호를 나타냄
#line 100 // 여기서부터 100라인이라고 지정함
#pragma : 컴파일러마다 다르게 동작함. 메뉴얼을 참고할 것미리 정의된 매크로 이름
__LINE__ : 줄 번호
__FILE__ : 파일 이름
__DATE__ : 월/일/년
__TIME__ : 시:분:초
__STDC__ : 1 --> ANSI C 표준에 부함됨을 의미주석
/* */ : C에서의 주석
// : 한줄 주석, C++에서 사용됨 (일반적으로 컴파일러가 c++ 이기에 사용가능)








