검색결과 리스트
프로그래밍에 해당되는 글 80건
- 2015.01.16 배열(Array)
- 2015.01.01 자료구조(Data Structure)
- 2015.01.01 Big-Oh 표기법(Big-Oh notation)
- 2014.12.31 알고리즘의 유형
- 2014.12.29 MAC OS X에 Lua 설치하기
- 2014.12.29 Lua 프로그래밍 언어와 Lua를 사용해서 만들어진 게임들
- 2014.11.09 C언어 공부를 정리하며
- 2014.11.09 7.8 기타 기능의 함수(Miscellaneous Functions)
- 2014.11.09 7.7 행 입출력(Line Input and Output)
- 2014.11.09 7.6 에러처리:stderr와 exit(Error Handling - Stderr and Exit)
글
C언어 할때 배열은 했지만 중요하니까 한번더!
배열은 연속된 메모리 공간을 차지하는 같은 데이터형들의 집합
정적인 데이터이기때문에 컴파일러는 이 정해진 크기만큼 공간만을 확보한다
배열의 선언방법은
데이터형 배열명[배열의 크기];
예를들어보자
int array[10];
integer형으로 array라는 배열을 10의 크기로 정의 하였다
이것은 두가지 의미인데 첫번째는 array라는 배열명은 10개의 정수가 저장된 공간의 선두번지를
둘째로는 sizeof(array)와 같이 하면 배열의 크기 즉 int형이 몇개나 저장될 수 있는가에 10이라는 값을 나타낼 뿐이다.
그 이외의 배열에 대한 조작은 모두 포인터의 조작으로 대치된다.
중요한점은 배열의 제일 첫 요소는 array[1]이 아니라 array[0]이며 마지막 요소는 array[10]이 아니라 array[9]이다 위에서의 10은 정말로 배열의 크기일 뿐이다.
컴파일러는 위의 정의에 의해서 int형 데이터가 10개로 저장될 공간을 정적 데이터 영역에 확보해두고 실제로 확보되는 배열의 크기는 int형 크기에 2에 10을 곱한 값, 즉 20바이트가 된다.
중요한것은 배열은 포인터에 대한 처리로 대치되기 때문에 array는 배열에 확보된 메모리 공간의 선두번지를 의미한다 그래서 array[4]는 *(array+4)와 완전히 동일하다 배열의 이름 즉 메모리 공간의 선두번지는 포인터와 동일하게 취급해도 되지만 배열의 이름은 포인터가 아니라는 것이다.포인터는 주소를 가리키는 변수이고 배열이름은 그자체를 가리키는 상수이다. 그래서 배열의 이름에 따로 공간을 할당하지는 않는다. 그래서 array를 포인터로 취급해서 그 값을 변경하려 하면 에러가 발생한다.
1차원 배열(one dimensional array)
배열에서 차수는 배열 요소를 지정하는데 몇개의 첨자가 배열의 크기를 지정하는것이 있는가에 의해서 지정되는데 1차원배열은 하나만 있으면 된다.
배열은 실행 후에 그값을 결정할 수있지만 정의하면서 초기값을 부여할 수 있다.
예를들어
int array[10] = {1,2,3,4,5,6,7,8,9,0};
;을 빼먹지 말자
이와같은 배열은 다음과 같이 메모리에 배치된다.
array가 가르키는곳
?? |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
0 |
?? |
1차원 배열은 위와 같아서 포인터의 연산이 제대로 먹히는 것이다.
다차원 배열(Multi dimensional array)
다차원 배열은 배열을 선언할때 원하는 차원만큼 첨자?를 지정하면 된다 보통 2차원을 많이 쓰고 3차원은 어쩌다가 가끔? 그이상은 잘 쓰지 않는다고 한다. 하지만 다차원 배열이라고 해도 그 근본은 2차원 배열과 같기 때문에 2차원 배열만 설명하겠다
2차원 배열 arra2를 선언하고 초기화를 해보자
int arra2[3][3] =
{{1,2,3},
{4,5,6},
{7,8,9}};
2차원 배열의 초기화에는 여러가지 방법이 있지만 위의 방법이 가장 좋다.
배열요소를 지정할때 위의 수를 행렬이라고 생각하면 된다(고등학교때 수학을 열심히 해야하는 이유!)
0열 1열 2열
0행 1, 2, 3
1행 4, 5, 6
2행 7, 8, 9
그래서 int array2[2][1]은 2행의 1열이니 8이다
int array2[0][1]은? 2다
array2는 2차원 배열이지만 메모리의 구조가 선형적 구조라서 메모리저장될때는 1차원 배열처럼 저장된다.
array2가 가리키는곳(array2는 정수 3개의 배열을 가리키는 포인터라고 생각 하면 된다)
?? |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
0 |
?? |
array2+1
array2+2
배열은 포인터로 설명이 가능하지만 2차원 배열인 경우 약간 복잡하다. 1차원 배열에서는 배열명이 배열공간의 선두를 가리키는 주소라고 했다. 그래서 array는 int형을 가리키는 주소로 생각하면 되었다.
하지만 array2는 3개의 int형의 공간을 가리키는 조소이다 마찬가지로 array2+1은 array2다음의 3개의 int형의 공간을 가리킨다.
C의 문법은 재귀적이라는 것을 생각하면 2차원 배열이 이런 복잡한 구조를 갖는다는 것이 이해가 갈것이다
1차원 배열을 함수의 인자로 넘기는 방법
1차원 배열을 함수의 인자로 넘기는 방법은 간단하다. 포인터로 표현하는 방법과 배열로 표현하는 방법이 있지만 이 둘은 같다.
다음은 배열을 진자로 받아서 배열요소들의 평균을 구하는 프로그램이다.
int average(int a[],int n)
{
int sum =0;
int i;
for (i=0;i<n;i++) {
sum+=a[i];
}
return (sum/n);
}
C에서 배열의 크기는 메모리 공간을 할당할 때만 필요하지 실행시에는 배열의 크기에 대해서 컴파일러가 신경쓰지 않는다 그래서 함수가 배열을 인지로 받을 때 그 배열이 몇개의 요소를 가지는지는 전혀 알 방법이 없다. 이런이유로 average()함수는 n이라는 배열의 크기를 인자로 따로 받는다. 그리고 인자로 받는 배열a에도 []로 배열표시만 했지 크기를 명시하지 않았다(해도 컴파일러가 무시한다)
물론 배열자체에 끝을 나타냄이 있으면 배열의 크기를 넘길 필요가 없다. 가장 전형적인 예가 C에서 문자열을 다루는 방식이다. C에서 문자열은 char형의 배열로 구현하는데 특별히 문자열의 크기에 신경을 쓰지 않음을 알고 있을 것이다. 배열을 읽어가다가 0이 읽어지면 배열의 끝임을 알게 되는 것이다. 이렇게 배열의 한계는 두가지가 있지만 선택은 본인 몫이다.
배열은 포인터와 동일한 표현이라고 했으므로 위의 average함수도 포인터의 표현으로 나타낼수 있을 것이다. 다음과 같이 함수의 헤더를 바꾸어도 상관없다.
int average(int *a,int n)
다음 코드는 1차원 배열을 함수의 인자로 넘기는 방법을 보여준다.
#include <stdio.h>
#define MAX 10
int average(int a[],int n)
{
int sum =0;
int i;
for (i=0;i<n;i++) {
sum+=a[i];
}
return (sum/n);
}
int main(int argc, const char * argv[]) {
int array[MAX];
int i;
printf("\nInput %d integer -> ",MAX);
for (i=0; i<MAX; i++) {
scanf("%d",array+i);
}
printf("\nAverage of %d integer is %d",MAX,average(array, MAX));
return 0;
}
2차원 배열을 함수의 인자로 넘기는 방법
2차원 배열을 함수 인자로 넘기는것은 주의해야 한다. C는 프로그램이 실행한 뒤에는 배열의 크기를 모른다고 하였기 때문에 1차원 배열에서는 함수의 인자로 배열을 넘길때 배열의 크기를 명시하지 않고 따로 배열의 크기르 정수로 넘겨주었다.
하지만 2차원 배열은 뭔가 그 원칙에 어긋나는 것 같다
2차원 배열을 사용하는 가장 빈번한 예는 행렬(Matrix)이다. 다음 input_matrix() 함수는 2x2 행렬을 키보드로 입력받는 함수이다
void input_matrix(int m[][2],int n)
{
int i,j;
printf("\n input %d by %d Matrix in row order ->",n,n);
for (i=0;i<n; i++) {
for (j=0; j<n; j++) {
scanf("%d",&m[i][j]);
}
}
}
배열의 크기를 모른다고 했는데 위의 input_matrix 함수는 인자에 int m[][2]라고 쓰여있어 2라는 크기가 들어갔음을 알수있다.
m을 포인터라고 보았을때 int m[][2]의 표현은 m이 두개의 int형의 공간을 가리키는 포인터이다. 즉 int m[][2]의 표현은 배열의 크기를 나타낸것이 아니라 m이 어떤 형의 데이터르 가리키는 포인터 인지 나타내는 것이다. 즉 m이 두개의 int혀이 공간을 가리킨다는 것은 알려졌지만 두개의 int형의 공간이 몇개나 있는지는 모른다. 결국 배열의 크기는 모른다는 것이다.
input_matrix 함수는 포인터 표현으로 나타낼수 있다 아래처럼 바꾸어도 지장이 없다
void input_matrix(int *(m[2]),int n)
포인터로 표현하니 의미가 더 명확하게 보인다. 2개의 int형 공간을 가리키는 포인터 m의 정체가 이제 확연하게 드러난다.
2차원 배열을 1차원 배열인것 처럼 사용할수도 있지만 그럴 필요까진 없을것 같다 굳이 하자면 할수 있지만...굳이 써보자면
void input_matrix(int *m,int n)
{
int i,j;
printf("\n input %d by %d Matrix in row order ->",n,n);
for (i=0;i<n; i++) {
for (j=0; j<n; j++) {
scanf("%d",m+i*n*j);
}
}
}
함수 호출은 다음과 같다.
void main()
{
int mat[2][2];
input_matrix(&mat[0][0],2);
...
}
조금은 기형적입니다. 왠만하면 보이는 대로 2차원 배열을 다룹시다!
연습으로 2x2의 정방행렬을 두개 입력받아서 곱을 출력하는 프로그램을 작성해 보자.
두행렬 A,B의 곱 C에 대입하는 알고리즘을 풀어 써보자
1.for(i는 0부터 N-1까지 1씩 증가) --> i는 C의 행
2.for(j는 0부터 N-1까지 1씩 증가) --> j는 C의 열
3.C[i][j]를 0으로 초기화 -->누적을 위해서 초기화
4.for(k는 0부터 N-1까지 1씩 증가)
5.C[i][j]에 A[i][k]*B[k][j]를 더함
이 알고리즘을 코드로 구현해 보면
#include <stdio.h>
#define MAX 2
void input_matrix(int m[][MAX],int n) //배열을 키보드로 입력받음
{
int i,j;
printf("\n input %d by %d Matrix in row order ->",n,n);
for (i=0;i<n; i++) {
for (j=0; j<n; j++) {
scanf("%d",&m[i][j]);
}
}
}
void print_matrix(int m[][MAX],int n)
{
int i,j;
printf("\n");
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
printf("%-6d",m[i][j]);
}
printf("\n");
}
}
void multiply_matrix(int m1[][MAX],int m2[][MAX],int m3[][MAX],int n)
{
int i,j,k;
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
m3[i][j] = 0;
for (k=0; k<n; k++) {
m3[i][j] += m1[i][j] * m2[k][j];
}
}
}
}
int main(void)
{
int mat1[MAX][MAX];
int mat2[MAX][MAX];
int mat3[MAX][MAX];
input_matrix(mat1, MAX);
input_matrix(mat2, MAX);
multiply_matrix(mat1, mat2, mat3, MAX);
printf("\n Answer : ");
print_matrix(mat3, MAX);
}
이렇게 나타낼수 있다.
다차원 배열을 함수의 인자로 넘기는 방법
이 방법은 2차원 배열을 함수의 인자로 넘기는 방법의 연장선상에 있다. 즉 다차원 배열을 함수의 인자로 넘길 떄에는 2차원 배열과 마찬가지로 가장 큰 블록을 가리키는 최자측 첨자를 비워두고 나머지 첨자는 그 크기를 명시하는 것이다
예를들어 3*4*2 크기를 가지는 int형의 tri 배열을 예로 들어 보겠다.
int tri[3][4][2];
int func(int t[][4][2])
{ ...
}
위와 같다.
그 이상도 마찬가지다
'프로그래밍 > 알고리즘과 자료구조' 카테고리의 다른 글
자료구조(Data Structure) (0) | 2015.01.01 |
---|---|
Big-Oh 표기법(Big-Oh notation) (0) | 2015.01.01 |
알고리즘의 유형 (0) | 2014.12.31 |
알고리즘 그리고 자료구조 (0) | 2014.10.26 |
설정
트랙백
댓글
글
프로그램을 작성할때에도 구조적인 작성이 필요하다
예를들어 전체적으로 지도를 그리듯이 윤곽을 잡고 기능을 분류,모듈로 작성한다음 다시 각 모듈을 세분화 하여 함수들을 작성하는 방법을 (Top -down Programming)이라고 하며 구조화 하는 프로그래밍의 중요한 기법이다
자료에 눈을 돌려 보아도 그냥 개념없이 흐트러져 있거나 외부조작에 대해 너무 개방적이면 이는 구조적이라고 할수 없다.
서로 연관있는 자료끼리 연견되어있으며 자료에 접근하는 방법을 제한하는 등의 짜여진 자료구조는 프로그램을 작성하는 데 아주 중요하다.
자료구조와 알고리즘은 아주 밀접하다. 자료구조가 복잡하면 알고리즘은 간단해지고 그 역이 성립한다 자료구조와 알고리즘의 복잡함을 타협하는 지혜가 필요하다.
그래서 배열,리스트,스택,큐,트리 로 하나씩 알아보겠다
'프로그래밍 > 알고리즘과 자료구조' 카테고리의 다른 글
배열(Array) (0) | 2015.01.16 |
---|---|
Big-Oh 표기법(Big-Oh notation) (0) | 2015.01.01 |
알고리즘의 유형 (0) | 2014.12.31 |
알고리즘 그리고 자료구조 (0) | 2014.10.26 |
설정
트랙백
댓글
글
앞에서 입력자료의수 N에 대해서 그 실행시간 함수 T(N)은 일정한 유형이 있음을 알아보았는데요 실제로는 이유형에 상수가 곱해지고 더해집니다.
실행시간에 대해서 오해하기 쉬운점은 나쁜유형의 알고리즘이라도 효율석있게 만들면 좋지 않을까? 인데 물론 잘만 프로그래밍한다면 바꿀수는 있지만 알고리즘 자체를 변경하는것은 불가능 합니다. 효율적인 프로그래밍은 유형에 곱하거나 더해지는것을 작게 하는것분 획기적인 시간단축을 위해서는 알고리즘 자체를 개선해야 합니다.
하나의 알고리즘을 여러사람이 프로그래밍 한다면 실행 결과의 함수는 모두 다를 뿐더러 이 알고리즘은 추상적인 방법인데 비해 프로그래밍은 정말 많은 변수가 있기때문에 서로다른 실행시간을 가져옵니다. 그래서 경험적으로 알고리즘 성능을 판단하는것은 옳지 못하기 때문에 이런 알고리즘 성능을 객관적으로 표현하는 기준이 바로 O표기법 입니다.
O 표기법의 정의는
만약 실행 시간 함수T(N)이 N0보다 큰 N에 대하셔 항상 C0F(N)보다 작거나 같은 C0와 N0가 존재한다면 T(N)은 O(F(N))이라고 합니다.
즉 N>=N0인 모든 N에 대하여 T(N)<=C0F(N)이 만족하면 T(N)=O(F(N))입니다.
실제 실행함수 T(N)이 같는 상수는 프로그래머의 능력에 따라 달라질수 있는 것이기 때문에 순수한 알고리즘 성능표시를 위해 상수요소를 없어야 하는데 이 상수 요소를 없앤 입력 자료수 N에 따른 실행시간만 나타낸것이 바로 O 표기법입니다
이 O표기법은 정의상 알고리즘 실생시간의 상한을 나타냅니다. 실행시간의 상한은 최악의 경우 에 해당한다는것도 알아둡시다. 즉 O표기법은 최악의 경우에 대한 입력 자료수 N에 대한 실행시간 함수 관계입니다.
예시로
T(N) = 3*N*N+1
T(N)은 4*N*N보다는 N이 1보다 큰 경우에 항상 작으므로 상수 4를 떼버리고 O(N^2)이 라고 말할 수 있습니다. 또한 4*N*N*N도 O(N^3)라고 말할수 있고 더 큰수도 가능하지만 이렇게 큰함수만 잡는것은 알고리즘 성능을 표헌하는데 큰 의미가 없습니다.
일반적으로 T(N)이 N의 다항식으로 나타날 떄는 최고차항만 의미가 있습니다. 그래서 T(N)이 최고차가 m이라면 O(N^m)이라고 말할수 있습니다.
하지만 O표기법을 과신하는것도 문제 가 있습니다
첫번째로 O표기법은 실행시간의 상한을 제공하기 때문에 실제로는 실행시간이 작을수도 있습니다
두번쨰로 알고리즘이 실행시간이 상한을 하는것은 실제 운용상 거의 나타나지 않습니다.
세번째로는 미정의 상수 C0는 충분히 작아야 합니다.
네번째로는 미정의 상수 N0역시 충분히 작아야 한다는 점 입니다
예를 들어 가장 빠른 정렬 알고리즘이라고 알려져 있는 퀵정렬의 경우 그 실행시간은 O(N^2)입니다 O표기법은 최악의 경우 실행시간의 상한을 나타내기 때문에 실제의 일반적인 경우 실행시간은 훨씬 적습니다. 퀵 정렬은 일반적으로 NlogN의 실행시간을 가져 매우 빠른 속도를 가집니다.
결론은 O표기법은 최악의 경우라도 넘지않는 실행시간의 함수이기 떄문에 일반자료에 대한 실행시간 보다는 훨씬 큰 값을 가진다. 일반적인 경우에는 매우 뛰어난 속도를 가지지만 최악의 경우에만 극도로 성능의 좋지 않는 알고리즘의 경우 O표기법은 과장되게 성능이 나쁜것으로 판단합니다.
--후일 추가 내용 다른 표기법과 시간적 공간적 소요량
'프로그래밍 > 알고리즘과 자료구조' 카테고리의 다른 글
배열(Array) (0) | 2015.01.16 |
---|---|
자료구조(Data Structure) (0) | 2015.01.01 |
알고리즘의 유형 (0) | 2014.12.31 |
알고리즘 그리고 자료구조 (0) | 2014.10.26 |
설정
트랙백
댓글
글
읽어보기 전에...:컴퓨터는 엄청 큰 계산기 랍니다. 그말은 수학을 조금은 알아야 한다는것이지요 하하하
읽어보시기 전에 로그,제곱,등은 알아두고 읽어보시는것이 이해가 더 잘될것 같습니다
1.
입력 자료수에 관계없이 일정한 시간을 갖는 알고리즘이다. 프로그램에서 대부분의 명령으로 한번이나 몇번만 실행된다. 전체적 프로그램이 이런경우라면 실행시간은 상수(1처럼)가 된다. 알고리즘을 설계하거나 테스트시 도전해볼만 하다.
log N.
입력자료 N에 따라라 실행시간이 Log N을 만족한다면 N이 증가함에 따라 실행시간이 조금씩 늘어난다. 커다란 문제를 해결할때 조금씩 잘게 쪼갤때 나타나는 알고리즘이다.로그 가 그렇듯이 base에 따라 결과가 달라지지만 그렇게 크게 다르지는 않다. 예를들어 N이 1000일때 밑이 10이라면 결과는 3이 나오지만 밑이 2라면 약 10이다 이차이는 매우 미미하다. 이 유형의 알고리즘은 매우 바람직한 실행시간을 가지는데 성능의 좋은 알고리즘은 대부분 Log N의 수행시간을 가진다.
N log N.
커다란 문제를 독립적인 작은 문제로 쪼개어 각각에 대해 독립적으로 해결하고, 나중에 다시 그것들을 하나로 모으는 알고리즘이다 N이 두배가 많아지면 실행시간은 두배보다 조금 더 많이 늘어난다.
N^2.
이 유형은 이중 루프 내에서 입력자료를 처리하는 경우에 나타난다. N값이 큰값이 되면 실행시간은 감당하지 못할정도 커진다 그러므로 많은 양의 입력자료에 대해서는 사용이 부적절 하다. N이 두배로 늘어나면 실행시간은 4배로 늘어난다.
N^3.
이 유형은 앞의 유형과 비슷하게 입력자료를 삼중 루프내에서 처리하는 경우에 나타난다 N값이 커짐에 따라 실행시간은 훨씬더 커지게 된다. 앞의 유형과 마찬가지로 많은 입력자료에 대해서는 부적절하며 문제가 있는 알고리즘이다 N이 두배가 늘어나면 실행시간은 8배로 늘어난다.
2^N
입력자료가 늘어남에 따라 급격하게 실행시간이 늘어난다. 흔하지는 않지만 알고리즘을 개발할떄 보인다. 하지만 개발되고 난후로 더좋은 알고리즘으로 개선된다. N이 두배로 늘어나면 실행시간은 제곱이 된다.
실행시간이 오래걸리는것 순서대로 알고리즘을 적어 보았는데요 가장 효율적인 유형은 logN과 NlogN 인것같습니다!
'프로그래밍 > 알고리즘과 자료구조' 카테고리의 다른 글
배열(Array) (0) | 2015.01.16 |
---|---|
자료구조(Data Structure) (0) | 2015.01.01 |
Big-Oh 표기법(Big-Oh notation) (0) | 2015.01.01 |
알고리즘 그리고 자료구조 (0) | 2014.10.26 |
설정
트랙백
댓글
글
먼저 www.lua.org 에 갑니다
깔끔하네요 다운로드를 눌러주세요
이런게 있군요 저 Building 에 가면 명령어가 있습니다 유심하게 봅니다
자 이제 터미널을 실행합니다
curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz
tar zxf lua-5.2.3.tar.gz
cd lua-5.2.3
make macosx test
이걸 그대로 터미널에 입력해주면 됩니다 해볼까요?
처음 명령어가 다운받는거군요
두번째는 압축을 푸는 명령어에요 그리고 압축이 풀린 폴더로 들어갑니다
테스트해보니 막 저럽니다 그럼 잘 되고 있는거에요
거의 다했어요 마지막 관리자 권한으로 루아파일을 복사해줍니다.
끝! 우리 전설의 프로그램 Hello World를 해볼까요?
print("Hello World") 끝입니다
세미콜론도 필요없습니다.....
마지막 ^d 는 EOF로 Control+D입니다.
네 정말 쉽네요
물론 첨부터 깔려있는 파이썬이나 펄보단 귀찮지만 뭐 ㅎㅎ 더 가벼우니!
자 이제 루아의 세계에 빠져봅시다!
'프로그래밍 > 잡다한 것들' 카테고리의 다른 글
Lua 프로그래밍 언어와 Lua를 사용해서 만들어진 게임들 (0) | 2014.12.29 |
---|
설정
트랙백
댓글
글
Lua 포르투칼 어로 달이 라는 뜻이라고 합니다 네 이름이 포르투칼 어니까 포르투칼어를 쓰는 포르투칼이나 브라질에서 만들었겠죠? 네 브라질 리우데 자네이로에 Luiz Henrique de Figueiredo, 호베르투 이에루잘림스시와 Waldemar Celes 이 세분이서 만든 프로그래밍 언어 입니다 중간에 한글이있는 분이 있는이유는 이분이 프로그래밍 루아라는 책을 쓰셨기 때문에 구분하려고 한글로 썼습니다.
확장언어와 스크립트 언어를 지향하고있어 충분히 작기때문에 많은 플랫폼에서 사용가능하고 무엇보다 C/C++과 궁합이 매우 좋아서 게임업계에서 많이 쓰인다고 하네요
http://en.wikipedia.org/wiki/Category:Lua-scripted_video_games
루아가 쓰인 게임들 리스트입니다 그중에 조금 유명한것만 간추려 보겠습니다
앵그리버드
발더스게이트
문명5(문명4는 파이썬 사용)
크라이시스
다크소울
페이블2
파크라이
개리모드
히어로즈오브마이트앤매직5
모노폴리 타이쿤
세인즈로우2,3,4
심시티4
심즈2
소닉 언리쉬드
워해머 40000 dawn of war 1,2
월드오브워크래프트
네 일단 무료고요 제가 주로 쓰는 cocos2d-x와 궁합도 잘맞아서 이번기회에 공부해 보려합니다
설치부터 기본적인 문법 그리고 가장 중요한 C와 어떻게 접착시키는지 보여드릴테니 기대해주세욥!
'프로그래밍 > 잡다한 것들' 카테고리의 다른 글
MAC OS X에 Lua 설치하기 (0) | 2014.12.29 |
---|
설정
트랙백
댓글
글
커닝헌과 데니스 리치가 쓴 The C Programming Language(TCPL)에 대해서는 여기까지 여기까지 하겠습니다
본래 8장과 뒤에 부록이 있지만 그것은 범용적인 C라기 보다는 UNIX시스템에 관련된 것이고 뒤의 부록은
인터넷을 검색해보면 금방 찾을수 있을 거라 생각합니다
이책이 옛날에 쓰여진 책이고 쓰여질 당시 OS는 UNIX나 DOS라서 거기에 맞게 저자가 예졔를 짜놓아서
지금과 맞이 않는 부분이 상당하게 있네요 일단은 한번은 익히는게 목적이라 그냥 썻지만 추후에
Microsoft-> Visual C++
OS X -> LLVM/Clang
Linux -> gcc
버전에 맞게 또 지금은 c11까지 나왔지만 나중에 c14가 나오면 그에 맞게 제나름대로 고쳐보겠습니다
사실상 어떤 OS에서도 쓸수있는 언어라면 C/C++/JAVA 정도이지만 오라클이 JAVA를 인수한후 좀 이상? 해진 면이 있는데요 C/C++을 훨씬 오래전부터 사용해왔고 라이브러리도 많으면서 OS나 게임만들때 필수적인 언어고 다른언어들 보다 덜 변하기 때문에 한번 익혀 두고 꾸준히 공부하면 정말 대체불가능한 프로그래머가 되지 않을까 싶습니다 물론 자료구조/알고리즘도 열심히 해야겠지만요!
이책은 300페이지가 안되고 뒤에 부록을 제외하면 정말 짧은책에 제가 C를 많이 접했기때문에 정말 후딱 공부할수 있었습니다만 C++는 비야네가 쓴 책부터 1000페이지가 넘고 포인터와 객체지향을 두개다 쓰기때문에 정리하기에는 오래 걸릴것 같습니다만 실제로 모바일 이나 3d콘솔게임 같은경우 C++을 사용하는 경우가 많기때문에 게임을 만들면서 천천히 공부해야겠습니다 즐기면서요! 아마 주중에 C++/cocos2d-x 주말에 C/알고리즘/자료구조를 정리하면서 저를 완성시킬것 같습니다
한국 게임 개발자들 화이팅!
'프로그래밍 > C' 카테고리의 다른 글
7.8 기타 기능의 함수(Miscellaneous Functions) (0) | 2014.11.09 |
---|---|
7.7 행 입출력(Line Input and Output) (0) | 2014.11.09 |
7.6 에러처리:stderr와 exit(Error Handling - Stderr and Exit) (0) | 2014.11.09 |
7.5 파일 엑세스(File Access) (0) | 2014.11.09 |
7.4 형식화된 입력:scanf(Formatted Input - Scanf) (0) | 2014.11.09 |
설정
트랙백
댓글
글
표준 라이브러리는 상당히 다양한 함수를 제공한다. 이 절에서는 그중 자주 쓰이는 것에 대해 설명하였다.
7.8.1 문자열 조작
<stdio.h>에 있는 strlen,strcpy,strcat,strcmp등의 문자열 함수에 대해서는 이미 언급하였다. 다음 예시에서 s는 char *이고 c와 n은 int 이다.
strcat(s,t) t를 s의 끝에 연결시킨다.
strncat(s,t,n) t중에 n개 문자를 s의 끝에 연결시킨다.
strcmp(s,t,) s<t,s==t나 s>t에 대해,-,0,+로 리턴한다.
strncmp(s,t,n) strcmp와 같은데 단지 처음의 n개의 문자만 비교한다.
strcpy(s,t) s에 t를 복사한다.
strncpy(s,t,n) t의 n개 문자를 s에 복사한다.
strlen(s) s에 길이를 리턴한다.
strchr(s,c) s에서 첫번째 c의 포인터를 리턴하거나 존재하지 않으면 NULL을 리턴한다.
strrchr(s,c) s에서 마지막 c의 포인터를 리턴하거나 존재하지 않으면 NULL을 리턴한다.
7.8.2 문자분류와 변환
<ctype.h>의 여러함수는 문자를 검색하거나 변환을 수행한다 다음 c는 unsigned char로 나타낼수 있는 int 거나 EOF이다
isalpha(c) c가 알파벳이면 0이아닌 숫자,아니면 0
isupper(c) c가 대문자면 0이아닌 숫자,아니면 0
islower(c) c가 소문자 0이아닌 숫자,아니면 0
isdigit(c) c가 숫자(digit)이면 0이아닌 숫자,아니면 0
isalnum(c) isalpha(c) 거나 isdigit(c)이면 0이아닌 숫자,아니면 0
lsspace(c) c가 공백,탭,newline,리턴,formfeed,수직탭이면 0이 아닌 숫자
toupper(c) c는 대문자로 변환된다.
tolower(c) c는 소문자로 변환된다.
7.8.3 ungetc 함수
표준라이브러리에서는 제 4장에서 제시한 ungetch보다 덜 제한된 형태로 사용되는 ungetc함수가 있다.
int ungetc(int c,FILE *fp)
는 문자 c를 파일 fp에 붙이고 c나 EOF(에러인 경우)중에 하나를 리턴한다. ungetc는 scanf,getc나 getchar와 같은 입력함수의 어떤것과도 함께 사용할수 있다
7.8.4 명령 실행
system(char *s)함수는 무자열 s에 포함된 명령어 라인의 명령(UNIX 명령이나 DOS 명령등)을 실행하고 현재의 프로그램으로 다시 되돌아온다. s의 내용으로 줄수 있는 것은 각각의 운영시스템에 따라 다르다 UNIX시스템의 평범한 예로 명령문
system("date");
는 프로그램 date를 실행시킨다. 이것은 표준 출력에서 그날의 시간과날짜를 출력한다. system은 실행된 명열으로 부터 시스템 의존적인 정수상태(integer status)를 리턴한다.
UNIX시스템에서 상태리턴(status return)은 exit함수가 리턴하는 값이다.
7.8.5 기억장소 관리
malloc와 calloc 함수는 메모리 블록을 동적으로 얻어낸다.
void *malloc(size_t n)
이 함수는 사용 가능한 n바이트를 가리키는 포인터를 리턴하는데 찾을 수 없으면 NULL을 리턴한다.
void *calloc(size_t n,size_t size)
는 지정된 크기의 n개의 대상체(object)의 배열을 위한 충분한 공간의 포인터를 리턴하거나 조건이 만족되지 않으면 NULL을 리턴한다. 저장장소는 0으로 초기화 한다.
malloc나 calloc에 의해 리턴된 포인터는 기억장소 정렬(alignment)에 맞게 되어 있지만, 다음과 같이 cast를 통해 적당한 형 변환을 해 주어야 한다.
int *ip;
ip = (int *)calloc(n,sizeof(int));
free(p)는 malloc나 calloc에 의해 얻어지는 p에 의해 가리켜지는 공간을 자유공간으로 만든다. 기억장소를 자유롭게 하는데는 아무런 순서제한이 없지만 calloc나 malloc 함수에 의존하지 않는 기억장소를 자유공간으로하려면 예상치 못한 에러가 발생된다.
기억장소가 자유공간이 되 후에 이 장소를 그냥 사용하면 에러이다 리스트(list)에서 기억장소를 자유롭게 하기위해 다음과 같은 loop를 사용하면 안된다.
for (p = head; p != NULL; p = p->next) /* WRONG */
free(p);
다음과 같이 하는 것이 올바른 방법이다.
for (p = head; p != NULL; p = q) {
q = p ->next;
free(p);
}
8.7에는 malloc와 비슷한 기억장소 할당기(storage allocator)가 소개되어 있는데 이함수는 순서에 관계없이 기억장소를 자유공간으로 만들 수 있다.
7.8.6 수학 함수
<math.h>에는 20가지 이상의 수학적인 함수(mathematical functions)가 있는데 여기서는 자주 사용하는 것을 소개하였다 하나 또는 두개의 double 매개변수를 취해서 double을 리턴한다.
sin(x) x의 sine,x는 라디안
cos(x) x의 cosine,x는 라디안
atan2(y,x) y/x의 arctangent,라디안
exp(x) 지수함수 e^x
log(x) 자연로그(x>0)
log10(x) 상용로그(x>0)
pow(x,y) x^y
sqrt(x) x의 제곱근(x>=0)
fabs(x) x의 절대값
7.8.7 난수 발생
rand()함수는 정수형 의사난수(pseudo-random) 0에서 <stdlib.h>에서 정의한 RAND_MAX까지의 범위에서 계산한다. 0보다는 크거나 같고 1보다는 작은 랜덤 부동소수점수를 방생시키는 방법은 다음과 같다.
#define frand() ((double) rand() / (RAND_MAX+1.0))
(만일 라이프러리가 이미 부동 소수점 난수에 대한 함수를 가지고 있다면 위의 것보다 통계상 특성이 더 좋을 것일 수가 많다)
srand(unsigned)함수는 rand함수에게 줄 seed를 세트한다. rand와 srand의 포터블(portable 이식이 자유로운)한 형태의 구현은 2.7에 잘 나타나 있다.
예제 7-9 isupper와 같은 함수는 공백을 절약하거나 시간을 절약하기 위한 형태로 구현이 가능하다 두 가능성을 조사하라.
'프로그래밍 > C' 카테고리의 다른 글
C언어 공부를 정리하며 (0) | 2014.11.09 |
---|---|
7.7 행 입출력(Line Input and Output) (0) | 2014.11.09 |
7.6 에러처리:stderr와 exit(Error Handling - Stderr and Exit) (0) | 2014.11.09 |
7.5 파일 엑세스(File Access) (0) | 2014.11.09 |
7.4 형식화된 입력:scanf(Formatted Input - Scanf) (0) | 2014.11.09 |
설정
트랙백
댓글
글
표준 라이브러리는 이전의 장들에서 사용한 getline 함수와 유사한 fgets 입력함수를 가지고 있다.
char *fgets(char *line,int maxline,FILE *fp)
fgets는 다음 입력행('\n'을 포함한)을 파일 fp로부터 문자열(즉 문자 배열)인 line에 읽어들이는데,최대 maxline-1 문자를 읽을 수 있다. 입력 완료된 라인은 '\0'에 의해 종료된다. 보통 fgets는 line을 리턴하는데,파일의 끝이너가 에러를 만났을 시에는 NULL을 리턴한다(getline 함수는 행의 길이를 리턴시키는데 이것이 더 쓸모 있는 값이다.0은 파일의 끝을 의미하게 된다.)
출력함수 fputs는 '\0'을 포함하지 않는 문자열을 파일에 출력시킨다
int fputs(char *line, FILE *fp)
에러가 발생하면 EOF를 리턴하고, 나머지 경우에는 0을 리턴한다
라이브러리 함수 gets와 puts는 fgets나 fputs와 유사하지만 stdin과 stdout에 적용되는 것이 자른 점이다. 혼란스럽게 gets는 마지막의 '\n'을 제거하지만 puts는 그것을 추가한다.
여기에서 fgets나 fputs와 같은 함수가 별로 특별한 점이 없다는 것을 보여주기 위해 프로그램 리스트를 다음에 실었다.
/* fgets: get at most n chars from iop */
char *fgets(char *s, int n, FILE *iop)
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(iop)) != EOF)
if ((*cs++ = c) == '\n')
break;
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
/* fputs: put string s on file iop */
int fputs(char *s, FILE *iop)
{
int c;
while (c = *s++)
putc(c, iop);
return ferror(iop) ? EOF : 0;
}
특별한 이유는 없지만 ferror과 fputs의 리턴값은 다르게 되어 있다 fgets를 사용해서 getline을 작성하는 것은 어렵지 않다.
/* getline: read a line, return length */
int getline(char *line, int max)
{
if (fgets(line, max, stdin) == NULL)
return 0;
else
return strlen(line);
}
예제 7-6 두 파일을 비교하여 내용이 다른 첫번째 행을 출력하게 하는 프로그램을 작성하라.
예제 7-7 제 5장 패턴찾는 프로그램을 수정하되 입력은 이름이 정해진 파일에서 받아들이거나, 파일 이름이 매개변수로 주어지지 않으면,쵸준 입력으로 받아들이도록 하라. 패턴이 일치하는 행이 발견될 때 파일 이름을 출력하게 할 수 있는가를 알아보라
예제 7-8 여러 개의 파일을 출력시키키는 프로그램을 작성하라. 각 프로그램은 새 페이지에서 시작 해야 하고 프로그램 위에 파일 이름이 출력되고 프로그램마다 1부터 시작하도록 페이지 번호를 붙인다.
'프로그래밍 > C' 카테고리의 다른 글
C언어 공부를 정리하며 (0) | 2014.11.09 |
---|---|
7.8 기타 기능의 함수(Miscellaneous Functions) (0) | 2014.11.09 |
7.6 에러처리:stderr와 exit(Error Handling - Stderr and Exit) (0) | 2014.11.09 |
7.5 파일 엑세스(File Access) (0) | 2014.11.09 |
7.4 형식화된 입력:scanf(Formatted Input - Scanf) (0) | 2014.11.09 |
설정
트랙백
댓글
글
cat 함수의 에러처리 방법은 그다지 좋은 편이 아니다 만약 파일중 하나가 어떤 이유로 액세스 될 수 없을때 에러메시지가 출력문의 끝에 나타난다. 이런 출력이 화면상에서 나타난다면 별 문제가 없지만 파이프라인을 통해 다른 파일이나 프로그래멩 들어가면 곤란하게 된다.
위의 문제를 해결하기 위해서 stderr로 불리는 또 하나의 stream을 stdin이나 stdout과 같은 방법으로 프로그램에서 지정한다.표준 출력의 방향이 다시 지정되더라도 stderr의 에러문은 화면상에 나타나게된다.
위의 것을 이용하여 cat를 표준 에러 파일에 에러메시지를 나타내도록 해보자.
#include <stdio.h>
/* cat: concatenate files, version 2 */
int main(int argc, char *argv[])
{
FILE *fp;
void filecopy(FILE *, FILE *);
char *prog = argv[0]; /* program name for errors */
if (argc == 1 ) /* no args; copy standard input */
filecopy(stdin, stdout);
else
while (--argc > 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n",
prog, *argv);
exit(1);
} else {
filecopy(fp, stdout);
fclose(fp);
}
if (ferror(stdout)) {
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2);
}
exit(0);
}
이 프로그램은 두가지 방법으로 에러를 알란다. 첫째 fprintf에 의해 만들어진 에러 메시지를 stderr로 보내면 에러 메시지가 사용자의 화면에 나타나게 된다. 프로그램 이름을 argv[0]으로부터 포함 했으므로 이프로그램이 다른것과 함께 사용 되더라도 에러의 근원지는 구별된다.
둘째 표준 라이브러리 함수 exit를 사용하는 방법이다. 그런데 이것이 호출되면 프로그램의 수행이 끝나게 된다. exit의 리턴 값은 다른 프로그램에서도 사용할 수 있으므로 그 프로그램 수행의 성공여부를 검사하는 프로그램을 작성할 수있다. exit가 0값을 리턴하면 모든게 잘되고 있는 것이고0이아닌 값을 리턴하면 대개 비정상적이라는 암시를 나타낸다 exit는 열린(open)파일에 대해 fclose를 호출하여 버퍼를 지우고 파일을 닫는다(close)
main 함수에서는 return expr 이라고 표현 하는 것과 exit(expire)이라고 표현하는 것은 똑같다. 그러나 exit는 다른 함수로부터 호출할 수 있는 유리한 점을 가지고 있다 함는 fp에 에러가 발생한다면 0이 아닌 값을 리턴한다.
int ferror(FILE *fp)
출력 에러는 매우 드물긴 하지만 발생할 여지가 있다(예:디스크가 꽉 차 있을경우).그렇기 때문에 프로그램에서이 점을 잘 검사해야 한다 함수 feof(FILE *)는 ferror의 유사형이다. 이 함수는 파일의 끝을 발견하면 0이 아닌값을 리턴한다.
int feof(FILE *fp)
여기서 예를 든 프로그램에서는 exit의 리턴값에 주의하지 않았지만 고수준의 프로그램에서는 리턴값 상태에 주의를 기해야만 한다.
'프로그래밍 > C' 카테고리의 다른 글
7.8 기타 기능의 함수(Miscellaneous Functions) (0) | 2014.11.09 |
---|---|
7.7 행 입출력(Line Input and Output) (0) | 2014.11.09 |
7.5 파일 엑세스(File Access) (0) | 2014.11.09 |
7.4 형식화된 입력:scanf(Formatted Input - Scanf) (0) | 2014.11.09 |
7.3 가변길이의 매개변수 리스트(Variable-length Argument Lists) (0) | 2014.11.08 |
RECENT COMMENT