반응형

1. Implement the dfs and bfs algorithms using the given graph and adjacency lists (Figure 1).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#define SIZE 8
#define FALSE 0  //boolean 연산을 위한 상수 설정
#define TRUE 1   //boolean 연산을 위한 상수 설정
typedef struct node *pn; //node형 포인터 자료형 pn
typedef struct node{
    int vertice;
    pn link;
}node; //node 자료형 안에는 node의 주소를 나타내는 link와 정수형 변수 vertice 포함
void add(pn a);
void dfs(int v);
void bfs(int v);
void addq(int *rear,int value);
int deleteq(int *front);
 
pn graph[SIZE]; //pn형 크기 8짜리 배열 graph
int visited[SIZE]; //int형 크기 8짜리 배열 visited, 방문한 노드 삽입
int queue[SIZE]; // 사이즈 8짜리 큐
 
int main(void)
{
pn cup; //pn형 변수 cup (포인터) 임시 저장소
int i;
for(i=0;i<SIZE;i++//graph 배열의 원소 초기화
{
    graph[i]=0;
}
add(&graph[0],1);    add(&graph[0],2);
add(&graph[1],0);    add(&graph[1],3);    add(&graph[1],4);
add(&graph[2],0);    add(&graph[2],5);    add(&graph[2],6);
add(&graph[3],1);    add(&graph[3],7);
add(&graph[4],1);    add(&graph[4],7);
add(&graph[5],2);    add(&graph[5],7);
add(&graph[6],2);    add(&graph[6],7);
add(&graph[7],3);    add(&graph[7],4);    add(&graph[7],5);    add(&graph[7],6); 
//주어진 그림대로 그래프 초기화 하는 과정
for(i=0;i<SIZE;i++){
cup=graph[i]; //graph[i]를 cup에 대입
printf("graph[%d]    ",i);
while(cup){ //cup이 0이 아니면(각 노드는 링크드 리스트로 구성되어 있어 마지막 노드는 0을 가리킴)
printf("%d ",cup->vertice); //cup->vertice 출력
cup=cup->link; //cup에 cup->link 대입
}
printf("\n"); //개행문자 출력
}
printf("DFS : ");dfs(0); printf("\n"); //dfs 실행
for(i=0;i<SIZE;i++)
{visited[i]=FALSE;} //visited된 노드들 초기화 (bfs 를 하려면 초기화 시켜줘야함)
printf("BFS : ");bfs(0); printf("\n"); //bfs 실행
return 0;
}
 
void add(pn *a,int value){  //그래프의 노드를 연결해주는 함수
    /*a에 해당하는 것이 노드를 가리키는 포인터, value는 추가할 값이다.
    a에 이미 연결되어 있는 메모리가 존재하면 계속 링크를 타고 가다가 링크가 0인
    메모리에 동적메모리할당 한것을 링크시켜 그곳에 value를 넣어준다
    add(&graph[0],1);    add(&graph[0],2); 예를들어 main함수에서 나온 것인데
    맨처음 graph[0]이 1을 갖는 메모리를 가리키고 1를 갖는 메모리가 2를 갖는 메모리를 가리키고
    2를 갖는 메모리의 링크는 0이다. 이런식으로 진행이 된다. 링크가 0인지 아닌지는 함수가 스스로 판단한다.*/
    pn *check=0//check를 NUL로 초기화,check는 이중포인터
    pn tmp = (pn)malloc(sizeof(node)); //tmp가 가리키는 곳에 node size 동적 메모리 할당
    check=a; //check가 가리키는 주소 = a가 가리키는 주소
    while(1){
        if((*check)==0){break;} // check가 가리키는 주소가 0이면 루프 탈출
    else if(((*check)->link)!=0){ //(*check)->link)!=0)이면 
        check=&((*check)->link); //check에 &((*check)->link) 대입
    }
    else//이외의경우
        check=&((*check)->link);  //check에 &((*check)->link) 대입하고 break
        break;}}
    *check=tmp; //check가 가리키는 주소에 tmp 대입
    (*check)->vertice=value; //value를 마지막 노드의 vertice 에 삽입
    (*check)->link=0//마지막 노드의 링크는 0
}
void dfs(int v){
    pn w; //pn형 변수 w (포인터)
    visited[v]=TRUE; //visited[v]에 1 대입
    printf("%5d",v); //5자리수로 해서 출력
    for(w=graph[v];w;w=w->link) //초기식 : w=graph[v], 조건식 : w가 존재하면(not 0) 증가식 : w에 w->link 대입
    {
        if(!visited[w->vertice]) //w가 가리키는 주소의 vertice가 방문하지 않은 노드라면
            dfs(w->vertice); //dfs 순환 호출
    }
}
void bfs(int v){
    pn w; //pn형 변수 w(포인터)
    int front=-1//front와 rear 를 -1로 설정(원형 큐)
    int rear=-1;
    printf("%5d", v); // 5의 전체 크기로 출력
    visited[v]=TRUE; //visited[v]에 true 대입(1)
    addq(&rear,v); //v를 원형 큐에 삽입
    while(front!=rear){ //front가 not rear 이면
    v=deleteq(&front); // 맨 앞 원소 delete
    for(w=graph[v];w;w=w->link){ //초기식 : w=graph[v], 조건식 : w가 존재하면(not 0) 증가식 : w에 w->link 대입
        if(!visited[w->vertice]) //w가 가리키는 주소의 vertice가 방문하지 않은 노드라면
        {
        printf("%5d", w->vertice); //w->vertice 출력
        addq(&rear,w->vertice); //w->vertice 큐에 삽입
        visited[w->vertice]=TRUE;  //visited[w->vertice]에 true 대입(1)
        }}}}
void addq(int *rear,int value){ //원형 큐에서 삽입
    *rear=(*rear)%SIZE;
    queue[++(*rear)]=value;
}
int deleteq(int *front){ //원형 큐에서 원소 삭제
    return queue[++(*front)%SIZE];
}
 
cs



2. Refine Prim’s algorithm, Kruskal’s algorithm into a C function that finds a minimum cost spanning tree.



Prim’s algorithm


Kruskal’s algorithm


graph


<Prim's Algorithm>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <stdio.h>
#include <stdlib.h>
 
typedef struct edge{ //edge 형 변수
    int left;  //int형변수 left,right,weight,u를 포함한다.
    int right;
    int weight;    
    int u;  // 어떤 집합에 속할지 정해준다. (여기서는 사용하지 않음)
}edge; 
 
void Prim(edge E[],edge T[]);
 
int Ecount=0;    //몇번째 E의 원소를 참조하고 있는가
int TVlength=1;  //노드가 들어갈 집합
int Tlength=0;   //dege T의 길이
int TV[7]={0,-1,-1,-1,-1,-1,-1}; //노드가 들어갈 집합, 몇번부터 시작하는지는 상관 없으나 0번부터 시작하라고 해서 0번만 넣고 나머지는 나올 수 없는 -1로 초기화
edge T[6];     //우리가 prim algorithm 에 의해 선택한 간선을 넣을 집합
edge E[9];    //기존에 주어진 set
 
int main(void)
{
    int i;    
    for(i=0;i<20;i++){
    T[i].left=-1;    T[i].right=-1;    T[i].u=-1;    T[i].weight=-1;}
    E[0].left=5;    E[0].right=0;    E[0].weight=10;    E[0].u=-1;
    E[1].left=0;    E[1].right=1;    E[1].weight=28;    E[1].u=-1;
    E[2].left=1;    E[2].right=2;    E[2].weight=16;    E[2].u=-1;
    E[3].left=2;    E[3].right=3;    E[3].weight=12;    E[3].u=-1;
    E[4].left=6;    E[4].right=3;    E[4].weight=18;    E[4].u=-1;
    E[5].left=4;    E[5].right=3;    E[5].weight=22;    E[5].u=-1;
    E[6].left=4;    E[6].right=6;    E[6].weight=24;    E[6].u=-1;
    E[7].left=5;    E[7].right=4;    E[7].weight=25;    E[7].u=-1;
    E[8].left=6;    E[8].right=1;    E[8].weight=14;    E[8].u=-1//책에 나와있는대로 초기화
    Prim(E,TV); //Prim 알고리즘 실행
    for(i=0;i<6;i++)
    {printf("%d %d %d %d\n",T[i].left,T[i].right,T[i].u,T[i].weight);} //확인을 위해 출력
    return 0;
}
void Prim(edge E[],int TV[]){
    int i=0int j; int k;int count=0int flag=0
    int tmpisl=-1; edge tmpedge;
    while(Tlength<6){
        /*for(u=0;u<TVlength;u++)
        {printf("%d",TV[u]);}
        printf("\n");*/
        tmpisl=-1;  tmpedge.left=-1; tmpedge.right=-1; tmpedge.u=-1; tmpedge.weight=100//tmp 각 원소 초기화 weight는 무조건 모든 간선 weight보다 크게
            for(j=0;j<9;j++){ //j는 0부터 9보다 작을 때까지
                count=0;  //count=0으로 초기화
                for(k=0;k<TVlength;k++)  //k=0부터 TVlength 보다 작을 때까지
                {if((TV[k]==E[j].left)) //TV[k]가  E[j].left와 같으면
                count++;} //count ++;
                for(k=0;k<TVlength;k++){ //k=0부터 TVlength 보다 작을 때까지
                if((TV[k]==E[j].right)) //TV[k]가  E[j].right와 같으면
                count++;} //count ++;
                printf("i=%d j=%d k=%d count=%d TLength=%d TVLength=%d\n",i,j,k,count,Tlength,TVlength);
                if(count==1){ //즉 E[j](간선)에 노드 TV[k]가 들어있으면 만약 count==2면 cycle 이라서 안됨
                    if(E[j].weight<tmpedge.weight) //E[j].weight<tmpedge.weight 면(작은걸 택해야 하니까)
                    {
                    tmpedge.left=E[j].left;
                    tmpedge.right=E[j].right;
                    tmpedge.u=E[j].u;
                    tmpedge.weight=E[j].weight; //tmp에 E[j]의 요소 대입
                    flag=0//flag에 0 대입
                    for(k=0;k<TVlength;k++){ //k=0부터 TVlength 아래까지
                        if(E[j].left==TV[k]) //E[j].left==TV[k]면 루프탈출
                            break;
                        else flag++//아니면 flag++
                    }
                    if(flag==TVlength) //flag가 TVlength면
                        tmpisl=E[j].left; //tmpisl 에 E[j].left대입
                    flag=0//flag 0으로 초기화
                    for(k=0;k<TVlength;k++){ //k=0부터 k<TVlength 까지
                        if(E[j].right==TV[k])  //E[j].right==TV[k]면 루프탈출
                            break;
                        else flag++;  //아니면 flag++
                    }
                    if(flag==TVlength) //flag==TVlength면
                        tmpisl=E[j].right; // tmpisl에 E[j].right대입;
                    /*TV에 없는걸 tempisl에넣어야함*/}
                }
            }
        TV[TVlength]=tmpisl; //TV에 tmpisl 대입
        TVlength++;  //TVlength 증가
        T[Tlength].left=tmpedge.left;
        T[Tlength].right=tmpedge.right;
        T[Tlength].u=tmpedge.u;
        T[Tlength].weight=tmpedge.weight; //tmp에있는 요소 T[Tlength]에 대입
        Tlength++//Tlength 증가
        i++//i증가
    }
        
}
cs




<Kruskal's Algorithm>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <stdlib.h>
 
typedef struct edge{ //edge 형 변수
    int left;  //int형변수 left,right,weight,u를 포함한다.
    int right;
    int weight;    
    int u; // 어떤 집합에 속할지 정해준다.
}edge;
 
void Kruskal(edge E[],edge T[]);
void select_sort(edge vector[],int size);
int notcycle(edge *e,edge T[]);
int makeuni(edge *e,edge T[]);
void jointuni(edge T[]);
 
int uni=0;   //전역변수, 집합의 이름(번호)를 정함
int Ecount=0//E의 인덱스
int Tlength=0//T의 길이(T에 원소 몇개인지)
edge T[6];    //edge형 배열 T 크기 6
edge E[9];    //edge형 배열 E 크기 9
int k;
 
int main(void)
{
    int i;    
    for(i=0;i<20;i++){
    T[i].left=-1;    T[i].right=-1;    T[i].u=-1;    T[i].weight=-1;} //T 초기화 (안나올 값으로)
    E[0].left=5;    E[0].right=0;    E[0].weight=10;    E[0].u=-1;
    E[1].left=0;    E[1].right=1;    E[1].weight=28;    E[1].u=-1;
    E[2].left=1;    E[2].right=2;    E[2].weight=16;    E[2].u=-1;
    E[3].left=2;    E[3].right=3;    E[3].weight=12;    E[3].u=-1;
    E[4].left=6;    E[4].right=3;    E[4].weight=18;    E[4].u=-1;
    E[5].left=4;    E[5].right=3;    E[5].weight=22;    E[5].u=-1;
    E[6].left=4;    E[6].right=6;    E[6].weight=24;    E[6].u=-1;
    E[7].left=5;    E[7].right=4;    E[7].weight=25;    E[7].u=-1;
    E[8].left=6;    E[8].right=1;    E[8].weight=14;    E[8].u=-1;  //교과서에 나온 것처럼 초기화
    Kruskal(E,T); //Kruscal 알고리즘 실행
    for(i=0;i<6;i++)
    {printf("%d %d %d %d\n",T[i].left,T[i].right,T[i].u,T[i].weight);} //출력으로 제대로 나왔나 확인
    return 0;
}
void Kruskal(edge E[],edge T[]){
edge temp;
select_sort(E,9); //E를 가중치의 크기대로 오름차순 정렬한다.
while((Tlength<6)&&(Ecount<9)){ //Tlength가 6보다 작고 Ecount가 9보다 작으면 루프 반복
temp.left=E[Ecount].left;temp.right=E[Ecount].right;temp.weight=E[Ecount].weight;    temp.u=E[Ecount].u; //temp의 각 요소에 E[Ecount]의 요소 대입
E[Ecount].left=-1;E[Ecount].right=-1;E[Ecount].weight=-1//E의 Ecount 원소는 삭제 (-1대입)
makeuni(&temp,T); //temp의 집합을 만들어준다.
jointuni(T); //같은 집합인데 번호가 다른 집합이 있으면 합해준다. temp를 제외한 T만 해준다. (cycle 검사때문에)
for(k=0;k<Tlength;k++){
    printf("T[%d].u=%d ",k,T[k].u);
}
printf("tmp.u : %d\n",temp.u); //T의 원소의 집합 번호와 temp의 집합 번호 확인
if(notcycle(&temp,T)) //싸이클이 생기지 않으면
{
T[Tlength].left=temp.left;T[Tlength].right=temp.right;T[Tlength].weight=temp.weight;    T[Tlength].u=temp.u; //T[Tlength]의 요소에 temp의 요소 대입
Tlength++;Ecount++//Tlength와 Ecount 하나씩 증가
}
else{Ecount++;} //싸이클이 생겼으면 Ecount만 증가
}}
 
void select_sort(edge vector[],int size){ //선택정렬 알고리즘 
    int i; int j; int temp; int index;
    for(i=0;i<size;i++)
    {
        index=i;
        for(j=i+1;j<size;j++)
        {
            if((vector[j].weight)<vector[index].weight){
            index=j;}
        }
        temp=vector[index].weight;
        vector[index].weight=vector[i].weight;
        vector[i].weight=temp;
        temp=vector[index].left;
        vector[index].left=vector[i].left;
        vector[i].left=temp;
        temp=vector[index].right;
        vector[index].right=vector[i].right;
        vector[i].right=temp;
    }
}
int notcycle(edge *e,edge T[]){ //간선이 cycle 형성 하는지 리턴값이 판별 1이면 notcycle, 0이면 cycle
    int check=0;
    int i;
    if(Tlength==0)  //Tlength가 0이면 1반환 
        return 1;
    for(i=0;i<Tlength;i++){ //i=0부터 Tlength 이전까지 반복
        if(e->u==T[i].u){ //e->u 와 T[i].u 가같으면 (집합이 같으면)
            if((e->left==T[i].left)||(e->left==T[i].right)||(e->right==T[i].left)||(e->right==T[i].right)){ //e의 left가 t의 left나 right와 같거나, e의 right가 t의 left나 right와 같거나
            check++;
            printf("Tlength=%d i=%d check=%d\n\n",Tlength,i,check);} //check 증가식
            if(check==2//즉 같은 집합 내에서 
            {return 0;}
        }}
    return 1;
}
int makeuni(edge *e,edge T[]){ //집합을 만드는 함수
    int i; int check=0;
    if(Tlength==0//Tlength가 0이면
    {e->u=uni++return e->u;} //e->u에 uni 대입하고 증가, e->u 리턴
    else{
        for(i=0;i<Tlength;i++)
        {
        if((e->left==T[i].left)||(e->left==T[i].right)||(e->right==T[i].left)||(e->right==T[i].right)) //e의 left가 t의 left나 right와 같거나, e의 right가 t의 left나 right와 같거나
        {check=1;    //check에 1 대입
        e->u=T[i].u; return e->u; //e->u 에 T[i].u 대입 (즉 둘은 같은 집합이됨) e->u 리턴
        break;}
        }
        if(check==0){ //check가 0이면
        e->u=uni++return e->u; //e->u에 uni대입하고 uni 증가시킴, e->u 리턴 (새로운집합)
        }}}
void jointuni(edge T[]){ //집합을 합치는 함수
    int i;
    for(i=0;i<Tlength;i++){ //i=0부터 Tlength 보다 작을때까지 반복
        if((T[i+1].left==T[i].left)||(T[i+1].left==T[i].right)||(T[i+1].right==T[i].left)||(T[i+1].right==T[i].right)){ //T[i+1]의 left가 T[i]의 left나 right와 같거나, T[i+1]의 right가 T[i]의 left나 right와 같거나,
            if(T[i+1].u<T[i].u)   //T[i+1].u가 T[i].u보다 작으면
                T[i].u=T[i+1].u; //T[i+1].u를 T[i].u에 대입
            else
                T[i+1].u=T[i].u; //작은 쪽으로 집합 번호를 매긴다.
        }}}
cs





반응형
반응형

두 개의 텍스트 파일을 서로 비교하는 프로그램을 작성하여 보자. 파일의 이름은 사용자에게 입력받는다. 만약 두개의 파일이 일치하면 "파일은 서로 일치함"을 출력하며 일치하지 않으면 일치하지 않는 첫 번째 문장을 다음과 같이 출력한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
int main(void)
{
    FILE *fp1;
    FILE *fp2;
    char a[SIZE];
    char b[SIZE];
    char f1[SIZE];
    char f2[SIZE];
    int bytes=0;
    printf("첫번째 파일 이름: ");
    gets(a);
    printf("두번째 파일 이름: ");
    gets(b);
    if((fp1=fopen(a,"r"))==NULL)
    {
        fprintf(stderr,"파일 열기 오류1\n");
        exit(1);
    }
    if((fp2=fopen(b,"r"))==NULL)
    {
        fprintf(stderr,"파일 열기 오류2\n");
        exit(1);
    }
    while(1)
    {
    fgets(f1,sizeof(f1),fp1); //fgets는 \n(개행문자) 나올 때까지 문자열을 받음 
    fgets(f2,sizeof(f2),fp2);
    if(strcmp(f1,f2)!=0// f1이 크면 양, f2가 크면 음, 같으면 0
    {
        printf("<< %s\n", f1);
        printf(">> %s\n", f2);
        break;
    }
    if(feof(fp1)!=0// 파일의 끝이면 not0, 끝이 아니면 0
    {
    printf("파일은 서로 일치함\n");
    break;
    }
    }
    return 0;
}
cs

만약 일치하지 않는 모든 문장을 나타내고 싶으면 strcmp 가 들어간 if 문에서 break; 만 빼주면 될 것이다.




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

인쇄 가능 문자 수 세기  (0) 2017.02.13
성적 평균 구하기  (0) 2017.02.12
fgets 함수  (0) 2017.02.11
파일 복사  (0) 2017.01.31
대문자로 변경  (0) 2017.01.31
반응형

하나의 파일을 다른 이름의 파일로 복사하는 프로그램을 작성하라. 이진 파일이라고 가정하고 fread()와 fwrite()를 사용한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int main(void)
{
    FILE *fpr=NULL;
    FILE *fpw=NULL;
    char buff[SIZE];
    int count=0;
    if((fpr=fopen("first.bin","rb"))==NULL)
    {
        printf("잘못된 파일 열기1\n");
        exit(1);
    }
    if((fpw=fopen("second.bin","wb"))==NULL)
    {
        printf("잘못된 파일 열기2\n");
        exit(1);
    }
    while((count=(fread(buff,sizeof(char),SIZE,fpr)))!=0)
    {
        printf("%d",count); //몇 개 세었는지 보려고
    fwrite(buff,sizeof(char),count,fpw);
    }
    return 0;    
}
cs

buff 와 fread 나 fwrite 를 쓸 때 덩어리의 크기를 int로 하면 오류가 생길 수 있습니다. 중간에 잘리는 경우(예를들어 09에서 0과 9사이에서 잘리는 경우)

데이터가 손실되는 것을 경험하였습니다. 따라서 1byte 단위인 char로 하는 것이 가장 안전합니다. (촘촘이 자르는 것이 가장 안전하겠죠??)

예를들어 int 형으로 한다면

1000100 을 복사하면 앞의 1000만 복사가 됩니다. 뒤에 100은 덩어리 (4byte) 가 꽉 안차서 손실이 되는 것 같아요 (정확한 것 아님 결과로부터 추론한 것임 (출력값은 1이됨)

정확한 것을 아시는 분은 댓글로 달아주세요)

그런데 10001000 을 하면  10001000 이 복사되고 출력값은 2가됩니다. 따라서 덩어리를 다 채워줘야 하는 것 같습니다.






반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

텍스트 파일 비교  (0) 2017.02.11
fgets 함수  (0) 2017.02.11
대문자로 변경  (0) 2017.01.31
텍스트 파일 비교  (0) 2017.01.31
암호화와 복호화  (0) 2017.01.16
반응형

텍스트 파일을 열어서 파일 안에 들어 있는 문자들을 모두 대문자로 변경하는 프로그램을 작성한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE 100
 
int main(void)
{
    FILE *fp=NULL;
    char a[SIZE];
    int i;
    if((fp=fopen("1.txt","r+"))==NULL)
    {
        printf("잘못된 파일 열기\n");
        exit(1);
    }
    fgets(a,SIZE,fp);
    printf("입력 파일 : ");
    for(i=0;a[i]!=NULL;i++)
    {
        printf("%c ", a[i]);
    }
    printf("\n");
    fseek(fp,0,SEEK_SET);
    for(i=0;a[i]!=NULL;i++)
    {
        a[i]=toupper(a[i]);
    }
    fputs(a,fp);
    fseek(fp,0,SEEK_SET);
    fgets(a,SIZE,fp);
    printf("출력 파일 : ");
    for(i=0;a[i]!=NULL;i++)
    {
        printf("%c ", a[i]);
    }
    printf("\n");
    return 0;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

fgets 함수  (0) 2017.02.11
파일 복사  (0) 2017.01.31
텍스트 파일 비교  (0) 2017.01.31
암호화와 복호화  (0) 2017.01.16
대소문자 변경  (0) 2017.01.16
반응형

두개의 텍스트 파일을 비교하여 같은지 다른지를 알려주는 프로그램을 작성하라.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
#define DEBUG 0
void open_file(FILE **fp1, FILE **fp2);
void check(FILE *fp1, FILE *fp2);
int main(void)
{
    FILE *fp1=NULL;
    FILE *fp2=NULL;
    int quit=0;
    while(1)
    {
    open_file(&fp1,&fp2);
    check(fp1,fp2);
    fseek(fp1,0,SEEK_SET);
    fseek(fp2,0,SEEK_SET);
    printf("종료하려면 9999 계속하려면 1\n");
    scanf("%d",&quit);
    if(quit==9999)
        break;
    getchar();
    }
    return 0;
}
void open_file(FILE **fp1, FILE **fp2)
{
    char name1[SIZE];
    char name2[SIZE];
    printf("첫번째 파일 이름: ");
    gets(name1);
    printf("두번째 파일 이름: ");
    gets(name2);
    if((*fp1=fopen(name1,"r"))==NULL)
    {
        printf("파일오픈불가능1\n");
        exit(1);
    }
    if((*fp2=fopen(name2,"r"))==NULL)
    {
        printf("파일오픈불가능2\n");
        exit(1);
    }
}
void check(FILE *fp1, FILE *fp2)
{
    char a,b;
    while(1)
    {
        a=fgetc(fp1);
        b=fgetc(fp2);
        #if DEBUG==1
        printf("%d %d\n", a,b);
        #endif
        if((feof(fp1)!=0&&feof(fp2)==0)||(feof(fp1)==0&&feof(fp2)!=0))
        {
            printf("두 파일은 서로 다릅니다(길이다름).\n");
            break;
        }
        if(a!=b)
        {
            printf("두 파일은 서로 다릅니다(글자다름).\n");
            break;
        }
        if(feof(fp1)!=0&&feof(fp2)!=0)
        {
            printf("두 파일은 서로 같습니다.\n");
            break;
        }
    }
}
cs



먼저 이중포인터를 사용한 이유는 fp1, fp2 자체가 파일을 가리키는 포인터죠. 따라서 처음에 초기값으로

NULL을 가리키고 있으니까 포인터가 가리키는 주소를 바꿔주려면 이중포인터를 사용해야해서 그렇습니다.

두번째로 중요한 것은 check 함수인데요. 여기서 '글자다름' 파트를 '길이다름' 파트보다 먼저 쓰게되면

무조건 다른 것이 글자다름으로 나오게 됩니다. 왜냐하면 텍스트 파일에서 EOF(파일의 끝)은 -1 값을

반환하게 되는데요 이것을 비교했을 때 글자다름을 먼저 수행하게 되면 무조건 -1과는 다른 값이 되므로

(길이가 다르기 때문에 다른 한쪽은 문자일 것이므로 어떠한 정수값을 가질 것임) 글자다름

으로 출력이 됩니다. 따라서 길이다름을 먼저 해주어야 길이가 다를 때는 길이다름으로 출력을 할 수 있습니다.

이것은 눈으로 확인할 수 있게 #if 로 표시를 해놓았습니다. 눈으로 확인하고 싶으시면 DEBUG 값을 1로 바꾸세요.

아래 스크린샷에도 추가해 놓았습니다.

파일 실행하기전 txt 파일로 아래와 같이 생성한 후에 시작해야합니다. (r타입으로 읽기 때문에)



이와같이 텍스트 파일에서는 파일의 끝이 -1로 표현되기 때문에 꼭 길이다름을 먼저 판별해 주어야 한다.

아니면 무조건 글자다름으로만 나온다. (길이가 다를 경우 -1은 무조건 다른 파일의 남은 글자와 다를테니까)




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

파일 복사  (0) 2017.01.31
대문자로 변경  (0) 2017.01.31
암호화와 복호화  (0) 2017.01.16
대소문자 변경  (0) 2017.01.16
정수 비트 이동  (0) 2017.01.16
반응형

암호화 방법 중의 하나는 암호화할 값을 키값과 비트 XOR 연산을 하는 것이다. 원래의 값을 복원하려면 다시 비트 XOR 연산을 하면 된다. 이 암호화 방법을 사용하여 사용자로부터 문자열을 입력받아서 암호화하고 다시 복호화하는 프로그램을 작성하라. 다중 소스 파일 형태로 작성하라.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
void print(char a[]);
int main(void)
{
    char s[50];
    int key=17;
    int i=0;
printf("문자열을 입력하세요: ");
gets(s);
print(s);
for(i=0;s[i]!='\0';i++)
{
    s[i]=s[i]^key;
}
printf("    ");
print(s);
printf("로 엔코딩됨.\n");
print(s);
for(i=0;s[i]!='\0';i++)
{
    s[i]=s[i]^key;
}
printf("    ");
print(s);
printf("로 디코딩됨.\n");
return 0;
}
void print(char a[])
{
    int i=0;
    for(i=0;a[i]!='\0';i++)
    {
        printf("%c", a[i]);
    }
}
cs


만약 키가 32 (100000) 이면 공백 이후 문자가 출력이 안되는데요 그 이유는 공백의 아스키 코드가 32(100000) 인데,

i am a boy 에서 i 이후 나오는 공백과 xor 연산을 하게 되는 것을 볼 수 있습니다. 그런데

같은 수를 XOR연산하면 무조건 000000 이나오고 이것의 아스키코드는 널문자(\0) 입니다. 따라서 조건문이 종료되버립니다.




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

대문자로 변경  (0) 2017.01.31
텍스트 파일 비교  (0) 2017.01.31
대소문자 변경  (0) 2017.01.16
정수 비트 이동  (0) 2017.01.16
2진수 출력  (0) 2017.01.16
반응형

비트 연산자를 이용하여 대소문자를 변경할 수 있다. 대문자의 아스키 코드는 모두 여섯번째 비트가 0이고 소문자의 경우에는 여섯 번째 비트가 모두 1이다. 따라서 XOR 연산을 이용하여 문자의 여섯 번째 비트를 바꿔주면 대소문자가 바뀌게 된다. 이 성질을 이용하여 사용자가 입력한 문자열의 대소문자를 바꾸는 프로그램을 작성하라. 앞 문제에서 작성한 display_bit() 함수를 사용한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main(void)
{
    char s[50];
    int i=0;
    printf("문자열을 입력하세요: ");
    gets(s);
    while(s[i]!='\0')
    {
        printf("%c",s[i]^32); //32는 2진수로 100000
        i++;
    }
    printf("\n");
    return 0;
}
cs

만약  32 (100000) 이면 공백 이후 문자가 출력이 안되는데요 그 이유는 공백의 아스키 코드가 32(100000) 인데,

i am a boy 에서 i 이후 나오는 공백과 xor 연산을 하게 되는 것을 볼 수 있습니다. 그런데

같은 수를 XOR연산하면 무조건 000000 이나오고 이것의 아스키코드는 널문자(\0) 입니다. 따라서 조건문이 종료되버립니다.


반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

텍스트 파일 비교  (0) 2017.01.31
암호화와 복호화  (0) 2017.01.16
정수 비트 이동  (0) 2017.01.16
2진수 출력  (0) 2017.01.16
비트 매크로  (0) 2017.01.15
반응형

사용자로부터 입력받은 정수를 비트 이동시키는 프로그램을 작성하여 보자. 먼저 정수 변수의 값을 입력받은 후에 이동시킬 방향, 이동할 거리를 사용자로부터 입력받는다. 비트 이동 전후에 정수의 값을 비트로 출력하도록 한다. 앞 문제에서 작성한 display_bit() 함수를 사용한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#define GET_BIT(n,pos) ((n)>>(pos)&0x01)
void display_bit(int value);
int main(void)
{
    int val, move, dist, nval;
    val=0;move=0;dist=0;nval=0;
    while(1)
    {
    printf("정수값을 입력하세요(종료 9999): ");
    scanf("%d"&val);
    if(val==9999)
        break;
    printf("왼쪽 이동은 0, 오른쪽 이동은 1을 입력하세요: ");
    scanf("%d"&move);
    printf("이동시킬 거리: ");
    scanf("%d"&dist);
    printf("이동 전: ");
    display_bit(val);
    if(move==0)
    {
        nval=(val<<dist);
        printf("이동 후: ");
        display_bit(nval);
    }
    else if(move==1)
    {
        nval=(val>>dist);
        printf("이동 후: ");
        display_bit(nval);
    }}
    return 0;
}
void display_bit(int value)
{
    int i,count;
    count=0;
    for(i=31;i>=0;i--)
    {
        if(count==4)
            {printf(" ");
        count=0;}
        if(GET_BIT(value,i))
            printf("1");
        else
            printf("0");
        count++;
    }
    printf("\n");
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

암호화와 복호화  (0) 2017.01.16
대소문자 변경  (0) 2017.01.16
2진수 출력  (0) 2017.01.16
비트 매크로  (0) 2017.01.15
공백 세기  (0) 2017.01.14
반응형

정수값을 받아서 2진수 형태로 출력하는 함수 display_bit(int value) 를 작성하여 보자. 6번에서 정의한 함수 매크로 GET_BIT(n, pos)를 이용한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#define GET_BIT(n,pos) ((n)>>(pos)&0x01)
void display_bit(int value);
int main(void)
{
    int num=0;
    printf("정수값을 입력하세요: ");
    scanf("%d"&num);
    display_bit(num);
    return 0;
}
void display_bit(int value)
{
    int i,count;
    count=0;
    for(i=31;i>=0;i--)
    {
        if(count==4)
            {printf(" ");
        count=0;}
        if(GET_BIT(value,i))
            printf("1");
        else
            printf("0");
        count++;
    }
    printf("\n");
}
cs





반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

대소문자 변경  (0) 2017.01.16
정수 비트 이동  (0) 2017.01.16
비트 매크로  (0) 2017.01.15
공백 세기  (0) 2017.01.14
원기둥의 부피  (0) 2017.01.14
반응형

비트를 조작하는 다음의 매크로를 작성하고 동작을 확인하라.

(a) SET_BIT(n, pos) : 변수 n 안에 있는 pos번째 비트를 1로 설정한다. 

(b) CLR_BIT(n, pos) :  변수 n 안에 있는 pos번째 비트를 0으로 설정한다.

(c) GET_BIT(n, pos) :  변수 n 안에 있는 pos번째 비트를 0으로 반환한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
#define SET_BIT(n,pos) ((n)|=(0x01<<(pos))) //변수 n pos번째 비트
#define CLR_BIT(n,pos) ((n)&=~(0x01<<(pos)))
#define GET_BIT(n,pos) ((n)>>(pos)&0x00//무조건 0으로 반환이니까
 
int main(void)
{
    int n,c,pos;
    n=0;c=0;pos=0;
    while(1){
    printf("정수를 입력하세요: ");
    scanf("%d"&n);
    printf("%016x\n", n);
    printf("1: pos번째 비트 1로 설정 2: pos번째 비트 0으로 설정\n 3: pos번째 비트 0으로 반환 4:종료\n");
    printf("번호를 입력하세요 : ");
    scanf("%d"&c);
    if(c==1)
    {
        printf("몇번째 비트? ");
        scanf("%d"&pos);
        SET_BIT(n,pos);
        printf("%016x\n", n);
    }
    else if(c==2)
    {
        printf("몇번째 비트? ");
        scanf("%d"&pos);
        CLR_BIT(n,pos);
        printf("%016x\n", n);
    }
    else if(c==3)
    {
        printf("몇번째 비트? ");
        scanf("%d"&pos);
        printf("%016x\n", GET_BIT(n,pos));
    }
    else if(c==4)
        break;
    }
    return 0;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

정수 비트 이동  (0) 2017.01.16
2진수 출력  (0) 2017.01.16
공백 세기  (0) 2017.01.14
원기둥의 부피  (0) 2017.01.14
배열 원소 일괄 초기화  (0) 2017.01.14
반응형

c가 공백 문자(탭, 스페이스, 줄바꿈 문자)이면 참이 되는 매크로 IS_SPACE(c)를 정의하여서 사용자가 입력한 문자열 중에서 공백 문자의 개수를 출력하여 보자.


1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#define SIZE 50
#define IS_SPACE(c) {int i;int count=0;for(i=0;i<SIZE;i++){if((c[i]==' ')||(c[i]=='\t')||(c[i]=='\n')){count++;}}\
                    printf("공백 문자의 개수는 %d개입니다.\n", count);}
int main(void)
{
char c[SIZE];
printf("문자열을 입력하세요:");
gets(c);
IS_SPACE(c);
return 0;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

2진수 출력  (0) 2017.01.16
비트 매크로  (0) 2017.01.15
원기둥의 부피  (0) 2017.01.14
배열 원소 일괄 초기화  (0) 2017.01.14
3개 정수 비교  (0) 2017.01.14
반응형

원기둥의 부피는 π(r^2)h 이다. 사용자로부터 반지름과 높이를 받아서 원기둥의 부피를 구하는 프로그램을 작성한다. 파이는 단순 매크로로 정의한다. 원기둥의 부피를 구하는 공식은 함수 매크로로 정의한다.


1
2
3
4
5
6
7
8
9
10
11
12
#define PI 3.14
#define VOLUME(r,h) ((r)*(r)*PI*(h))
#include <stdio.h>
int main(void)
{
int rad, hei;
rad=0;hei=0;
printf("반지름과 높이를 입력하세요: ");
scanf("%d %d"&rad, &hei);
printf("원기둥의 부피는 %f입니다.\n", VOLUME(rad,hei));
return 0;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

비트 매크로  (0) 2017.01.15
공백 세기  (0) 2017.01.14
배열 원소 일괄 초기화  (0) 2017.01.14
3개 정수 비교  (0) 2017.01.14
소스에 대한 질문 답하기  (0) 2017.01.13
반응형

배열 원소의 값을 모두 지정된 값으로 초기화하는 ARRAY_INIT(array, size, value)를 작성하여 테스트하여 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define ARRAY_INIT(array,size,value) {int i;for(i=0;i<size;i++){*(array+i)=value;}}
#define SIZE 10
#include <stdio.h>
int main(void)
{
    int a[SIZE];
    int s=0;
    int i;
    printf("값을 입력하세요 : ");
    scanf("%d"&s);
    ARRAY_INIT(a,SIZE,s);
    for(i=0;i<SIZE;i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

공백 세기  (0) 2017.01.14
원기둥의 부피  (0) 2017.01.14
3개 정수 비교  (0) 2017.01.14
소스에 대한 질문 답하기  (0) 2017.01.13
생명 게임(game of life - John H. Conway)  (0) 2017.01.13
반응형

3개의 정수 중에서 최소값을 구하는 매크로 GET_MIN(x,y,z)를 정의하고 이것을 이용하여서 사용자로부터 받은 3개의 정수 중에서 최소값을 계산하여서 출력하는 프로그램을 작성한다.


1
2
3
4
5
6
7
8
9
10
11
#define GET_MIN(x,y,z) ((x)<(z)?((x)<(y)?(x):(y)):((y)<(z)?(y):(z)))
#include <stdio.h>
int main(void)
{
    int i,j,k;
    i=0;j=0;k=0;
    printf("3개의 정수를 입력하세요: ");
    scanf("%d %d %d"&i, &j, &k);
    printf("최소값은 %d입니다.\n", GET_MIN(i,j,k));
    return 0;
}
cs



반응형
반응형

다음 소스에 대한 질문에 답하라.


1
2
3
4
5
6
7
8
9
10
11
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
        printf("result=%f\n", result);
        result*=x;
    }
    return result;
}
cs

(a)전처리기 지시자 #ifdef를 사용하여 DEBUG가 정의되어 있는 경우에만 화면 출력이 나오도록 하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define DEBUG  
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
#ifdef DEBUG // #if defined(DEBUG)
        printf("result=%f\n", result);
#endif
        result*=x;
    }
    return result;
}
cs

(b)#if를 사용하여 DEBUG가 2일 경우에만 화면 출력이 나오도로 수정하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define DEBUG 2
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
#if (DEBUG ==2)
        printf("result=%f\n", result);
#endif
        result*=x;
    }
    return result;
}
cs
(c)#if를 사용하여 DEBUG가 2이고 LEVEL이 3인 경우에만 화면 출력이 나오도록 수정하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define DEBUG 2
#define LEVEL 3
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
#if ((DEBUG ==2)&&(LEVEL==3))
        printf("result=%f\n", result);
#endif
        result*=x;
    }
    return result;
}
cs
(d)문장 1을 수정하여 소스파일에서 현재의 행 번호가 함께 출력되도록 하라.

1
2
3
4
5
6
7
8
9
10
11
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
        printf("result=%f line number=%d\n", result,__LINE__);  //1
        result*=x;
    }
    return result;
}
cs
(e)POWER_TYPE이라는 매크로를 정의하여 POWER_TYPE이 0이면 결과값을 int형으로 반환하도록 하고 POWER_TYPE이 1이면 결과값을 double형으로 
반환하도록 하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define POWER_TYPE 1
 
double power(int x, int y)
{
    int i;
#if(POWER_TYPE==0)
    int result=1;
    for(i=0;i<y;i++)
    {
        printf("result=%d\n", result);
        result*=x;
    }
#elif(POWER_TYPE==1)
    double result=1.0;
    for(i=0;i<y;i++)
    {
        printf("result=%f\n", result);
        result*=x;
    }
#endif
    return result;
}
 
cs


(f)#if를 이용하여 문장 1을 주석처리하여 보라.


1
2
3
4
5
6
7
8
9
10
11
12
13
double power(int x, int y)
{
    double result=1.0;
    int i;
    for(i=0;i<y;i++)
    {
#if 0
        printf("result=%f\n", result);
#endif
        result*=x;
    }
    return result;
}
cs


반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

배열 원소 일괄 초기화  (0) 2017.01.14
3개 정수 비교  (0) 2017.01.14
생명 게임(game of life - John H. Conway)  (0) 2017.01.13
2차원 배열 복사  (0) 2017.01.06
디지털 영상  (0) 2017.01.06
반응형

생명 게임(game of life)라고 불리는 인구 증가 게임을 구현하여 보자. John H. Conway에 의해 발명된 생명 게임은 출생과 생존, 죽음의 모델을 가정한다. 이 게임은 가로와 세로로 20개씩의 셀을 갖는 보드 위에서 게임을 한다. 각 셀은 비어 있거나, 생명체를 나타내는 0 값을 가질 수 있다. 각 셀은 8개의 이웃을 갖는다. 생명체의 다음 세대는 다음 규칙에 따라 결정된다.

(a)출생-3개의 이웃에 사람이 살면 현재의 위치에서 사람이 탄생한다.

(b)죽음-4개 이상의 이웃에 사람이 살면 과밀로 인해 죽게 된다. 둘 보다 적은 이웃에만 사람이 살면 외로움으로 죽게 된다.

(c)생존-둘 또는 셋의 이웃에 사람이 살면 현 위치의 사람은 다음 세대까지 생존하게 된다. 예를 들어서 다음 그림은 하나의 세대에서 다음 세대로 

진행되는 모습을 보여 준다.


나는 생존을 1, 죽음을 0으로 표현 하였고 죽음과 생존을 한가지 함수로 표현하였다. 그리고 순서대로 함수가 진행 되는데 전게 바뀌면 다음 값의 결과가 바뀌어 버리니까 또다른 크기의 빈 배열을 만들어 그곳에다가 값들을 넣고 마지막에 한꺼번에 복사하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#define SIZE 20
void printing(int a[][SIZE]);
void copy1(int ori[][SIZE],int cpy[][SIZE]);
void birth(int ori[][SIZE],int cpy[][SIZE]);
void death(int ori[][SIZE],int cpy[][SIZE]);
int main(void)
{        int ori[SIZE][SIZE]={
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
        int copy[SIZE][SIZE]={0,};
    int check=0;
    while(1){check=0;
    printf("계속하려면 1 종료하려면 2\n");
    printing(ori);
    birth(ori,copy);
    death(ori,copy);
    copy1(ori,copy);
    scanf("%d"&check);
    if(check==2)
        break;}
    return 0;}
void birth(int ori[][SIZE],int cpy[][SIZE])
{    int count=0;
    int *p= &ori[0][0];
    int *endp= &ori[SIZE-1][SIZE-1];
    int *cp=&cpy[0][0];
    while(p<=endp){
    if(*(p-SIZE-1)==1)
        count++;
    if(*(p-SIZE)==1)
        count++;
    if(*(p-SIZE+1)==1)
        count++;
    if(*(p+1)==1)
        count++;
    if(*(p-1)==1)
        count++;
    if(*(p+SIZE-1)==1)
        count++;
    if(*(p+SIZE)==1)
        count++;
    if(*(p+SIZE+1)==1)
        count++;
    if(*p==0&&count==3)
        *cp=1;
    count=0;
    p++;cp++;
    }}
void printing(int a[][SIZE])
{    int i,j;
    for(i=0;i<SIZE;i++)
    {for(j=0;j<SIZE;j++)
    {printf("%d ", a[i][j]);}
    printf("\n");}}
void copy1(int ori[][SIZE],int cpy[][SIZE])
{    int *p= &ori[0][0];
    int *endp= &ori[SIZE-1][SIZE-1];
    int *cp=&cpy[0][0];
    while(p<=endp)
    {*p=*cp;
    p++;cp++;}}
void death(int ori[][SIZE],int cpy[][SIZE])
{    int count=0;
    int *p= &ori[0][0];
    int *endp= &ori[SIZE-1][SIZE-1];
    int *cp=&cpy[0][0];
    while(p<=endp){
    if(*(p-SIZE-1)==1)
        count++;
    if(*(p-SIZE)==1)
        count++;
    if(*(p-SIZE+1)==1)
        count++;
    if(*(p+1)==1)
        count++;
    if(*(p-1)==1)
        count++;
    if(*(p+SIZE-1)==1)
        count++;
    if(*(p+SIZE)==1)
        count++;
    if(*(p+SIZE+1)==1)
        count++;
    if(*p==1&&((count>=4)||(count<2)))
        *cp=0;
    else if(*p==1&&(count==2||count==3))
        *cp=1;
    count=0;
    p++;cp++;}}
cs



이 게임의 패턴은 아래 사이트에서 확인할 수 있다. 여러가지를 넣어서 확인하여 보자.


https://namu.wiki/w/%EC%BD%98%EC%9B%A8%EC%9D%B4%EC%9D%98%20%EC%83%9D%EB%AA%85%20%EA%B2%8C%EC%9E%84


하는데 4일이나 걸렸네요.. 또다른 배열에 복사한다는 것을 생각을 못해서.. 후련합니다.




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

3개 정수 비교  (0) 2017.01.14
소스에 대한 질문 답하기  (0) 2017.01.13
2차원 배열 복사  (0) 2017.01.06
디지털 영상  (0) 2017.01.06
학생 성적 평균 구하기  (0) 2017.01.06
반응형

2차원 배열을 다른 2차원 배열로 복사하는 array_copy(char array1[], char array2[], int size) 함수를 구현하고 테스트하여 보라. 수행 속도를 위하여 배열 첨자 방법 대신에 포인터를 사용하라.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#define HEIGHT 5
#define WIDTH 10
void print(int array[][WIDTH]);
void copy(int array1[][WIDTH],int array2[][WIDTH]);
int main(void)
{    
    int image1[HEIGHT][WIDTH]={{0,0,0,0,9,0,0,0,0,0},
    {1,0,0,9,9,0,0,0,0,0},
    {5,0,9,0,9,0,0,0,0,4},
    {4,0,0,0,8,0,0,2,0,0},
    {3,0,0,0,9,0,0,0,0,8}};
    int image2[HEIGHT][WIDTH]={{0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0}};
    printf("이미지1 : \n");
    print(image1);
    printf("이미지2 : \n");
    print(image2);
    copy(image1,image2);
    printf("복사된이미지2 : \n");
    print(image2);
return 0;    
}
void print(int array[][WIDTH])
{
int i,j;
for(i=0;i<HEIGHT;i++)
        {for(j=0;j<WIDTH;j++)
        {
            printf("%3d ", array[i][j]);
        }
        printf("\n");
    }
}
void copy(int array1[][WIDTH],int array2[][WIDTH])
{
    int *p1, *endp1;
    int *p2;
    p1=&array1[0][0];
    p2=&array2[0][0];
    endp1=&array1[HEIGHT-1][WIDTH-1];
    while(p1<=endp1)
    {
        *p2=*p1;
        p1++;p2++;
    }
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

소스에 대한 질문 답하기  (0) 2017.01.13
생명 게임(game of life - John H. Conway)  (0) 2017.01.13
디지털 영상  (0) 2017.01.06
학생 성적 평균 구하기  (0) 2017.01.06
내림차순 정렬  (0) 2017.01.06
반응형

디지털 영상은 보통 2차원 배열로 표현된다. 각 배열 원소는 픽셀이라고 불린다. 흑백 영상의 경우, 하나의 픽셀은 보통 0에서 255의 값을 가지며 0은 검정색을, 255는 흰색을 나타낸다. 영상이 unsigned char image[ROWS][COLS]에 저장되어 있다고 가정하고 몇가지의 간단한 영상 처리 연산들을 포인터를 이용하여 구현하여 보자. 영상 처리된 겨로가는 화면에 각 픽셀의 값을 숫자로 표시한다.

(a) : 이진화 : 각 픽셀의 값이 임계값보다 낮으면 0으로 만들고 임계값보다 높으면 255로 만든다. (나는 5이상이면 255,  5미만이면 0으로 하였음)

(b) : 반전 : 영상의 흑백을 반전시킨다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#define HEIGHT 5
#define WIDTH 10
void print(int array[][WIDTH]);
void binarization(int array[][WIDTH]);
void reverse(int array[][WIDTH]);
int main(void)
{    
    int image[HEIGHT][WIDTH]={{0,0,0,0,9,0,0,0,0,0},
    {1,0,0,9,9,0,0,0,0,0},
    {5,0,9,0,9,0,0,0,0,4},
    {4,0,0,0,8,0,0,2,0,0},
    {3,0,0,0,9,0,0,0,0,8}};
    printf("원본 : \n");
    print(image);
    printf("이진화 : \n");
    binarization(image);
    print(image);
    printf("반전 : \n");
    reverse(image);
    print(image);
return 0;    
}
void print(int array[][WIDTH])
{
int i,j;
for(i=0;i<HEIGHT;i++)
        {for(j=0;j<WIDTH;j++)
        {
            printf("%3d ", array[i][j]);
        }
        printf("\n");
    }
}
void binarization(int array[][WIDTH])
{
    int *p, *endp;
    p=&array[0][0];
    endp=&array[HEIGHT-1][WIDTH-1];
    while(p<=endp)
    {
        if(*p>=5)
            {*p=255;}
        else if(*p<5)
            {*p=0;}
        p++;
    }
}
void reverse(int array[][WIDTH])
{
    int *p, *endp;
    p=&array[0][0];
    endp=&array[HEIGHT-1][WIDTH-1];
    while(p<=endp)
    {
        if(*p==0)
            {*p=255;}
        else if(*p==255)
            {*p=0;}
        p++;
    }
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

생명 게임(game of life - John H. Conway)  (0) 2017.01.13
2차원 배열 복사  (0) 2017.01.06
학생 성적 평균 구하기  (0) 2017.01.06
내림차순 정렬  (0) 2017.01.06
가장 큰 값  (0) 2017.01.05
반응형

학생들의 성적이 scores라는 2차원 배열에 저장되어 있다고 가정하자. scores의 행은 한 학생에 대한 여러 번의 시험 성적을 나타낸다. scores의 열은 한 시험에 대한 여러 학생들의 성적이다. 학생별로 성적의 평균을 구하려고 한다. 2차원 배열의 각 행이 1차원 배열임을 이용하여 다음과 같이 1차원 배열의 평균을 구하는 함수 get_average()를 호출하여 각 학생에 대한 평균 성적을 계산하여 보라.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#define ROW 3
#define COL 4
double get_average(int list[], int n);
int main(void)
{
    int scores[ROW][COL]={{90,90,90,90},{80,80,80,80},{70,70,70,70}};
    int i;
    double value;
    value=0;
    for(i=0;i<ROW;i++)
    {
    value=get_average(scores[i],COL); //2차원배열이라서 scores[i]는 포인터, scores도 포인터
    printf("%d번째 학생의 평균 : %lf\n", i,value);
    }
    return 0;
}
double get_average(int list[], int n)
{
int average=0;
int i;
for(i=0;i<n;i++)
{
average+=*(list+i);  //list[i]
}
average/=n;
return average;
}
cs




반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

2차원 배열 복사  (0) 2017.01.06
디지털 영상  (0) 2017.01.06
내림차순 정렬  (0) 2017.01.06
가장 큰 값  (0) 2017.01.05
문자열의 배열 출력  (0) 2017.01.05
반응형

문자열을 가리키고 있는 포인터의 배열을 인수로 받아서 문자열을 알파벳 순으로 정렬시키는 함수 sort_strings()를 작성하고 테스트하여 보라. 다음과 같은 원형을 가진다.


진짜 오래걸렸네요.. 괄호 안쳐서 2시간동안 해맸네요 짜증... ㅜ,ㅜ

각 포인터가 배열이니까 첫글자만 비교해서 서로 교환해주면 됩니다.. (교환하기 위해선 빈 물 컵이 있어야 한다는 것.. 잊지 않으셨죠??)

string[0] 은 포인터 string 은 이중포인터 tmp는 포인터 .. 점점 더 헷갈리는 느낌입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#define SIZE 3
void sort_strings(char *s[], int size);
int main(void)
{
    char *string[SIZE]={"mycopy","src","dst"};
    int i;
    sort_strings(string,SIZE);
    for(i=0;i<SIZE;i++)
    {
    printf("%d번째 문자열 : %s\n", i, string[i]);
    }
    return 0;
}
void sort_strings(char *s[], int size)
{
    int i, j;
    char *tmp=NULL;
    for(i=0;i<size;i++){
    for(j=i+1;j<size;j++)
    {
    if(*s[i]>*s[j])
        {tmp=s[i];
    s[i]=s[j];
    s[j]=tmp;}
    }}
}
cs





반응형

'컴퓨터 & 프로그래밍 & 전자공학 > C언어' 카테고리의 다른 글

디지털 영상  (0) 2017.01.06
학생 성적 평균 구하기  (0) 2017.01.06
가장 큰 값  (0) 2017.01.05
문자열의 배열 출력  (0) 2017.01.05
2차원 배열 합  (0) 2017.01.04

+ Recent posts