ACAIT

[C] 0501_9주차 Chapter 08 본문

전공 및 코드/C프로그래밍

[C] 0501_9주차 Chapter 08

831x99 2023. 5. 7. 22:33
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#define _CRT_SECURE_NO_WARNINGS
 
#include <stdio.h>
 
void main() {
    // 9주차 0501 배열
    // 9-1) 변수보다 배열이 불러들이는 속도가 빠름. 처리 속도 빠르고 짧은 코드가 좋음.
    // 배열: 여러 변수 나란히 연결하는 개념. 
    // 각 변수는 여러 변수 연속 선언을 해도 주소값(&)이 이어지지 않아서 메모리에 저장된 값을 각각 찾는 데에 오래 걸림.
    // 배열로 선언한 것들은 나란히 이어져 있으니 찾는 속도가 빠름.
    // 배열 선언 방법: 데이터타입 배열명[개수] => 개수는 그대로, 첨자는 0부터.
    
    int aa[4];
    int hap;
 
    printf("1번 숫자: ");
    scanf("%d"&aa[0]);
    printf("2번 숫자: ");
    scanf("%d"&aa[1]);
    printf("3번 숫자: ");
    scanf("%d"&aa[2]);
    printf("4번 숫자: ");
    scanf("%d"&aa[3]);
 
    hap = aa[0+ aa[1+ aa[2+ aa[3];
    printf("합: %d", hap);
 
 
    // 반복문 + 배열 = 효율성 극대화.
    int aa[4];
    int hap;
    int i;
 
    for (i = 0; i <= 3; i++) {
        printf("%d번 숫자: ", i+1);
        scanf("%d"&aa[i]);
 
        hap = hap + aa[i];
    }
 
 
    // 배열 초기화: int aa[4] = {100, 200, 300, 400};
    // int aa[] = {100, 200, 300, 400}; => 개수(첨자) 지정하지 않아도 됨.
    // 값 초기화 없이 선언만 하면 쓰레기값 들어감.
    // 초기화 값 개수가 적으면 값 주어진 것 외에는 0이 들어감. 
    // 직접 0으로 적어도 되고 자동으로도 0 입력.
    // 배열 1000개 모두 0 초기화 => int aa[1000] = {0};
    // 배열 개수보다 초기화 값이 많으면 컴파일 오류.
 
 
    // 265 page 8-5.c
    int aa[100], bb[100];
    int i, j;
 
    for (i = 0; i <= 100; i++) {
        aa[i] = i * 2;
    }
    for (j = 99; j >= 0; j--) {
        bb[i] = aa[j]
    }
 
 
    // 배열 크기(개수) sizeof() 활용. 
    // 배열크기변수 = sizeof(배열명(배열전체사이즈)) / sizeof(배열데이터형식);
 
 
 
    // 9-2) 배열과 문자열
    // 정수형 배열, 문자형 배열(마지막에 '\0' 개행문자 필수)
    // 문자열 반대로 출력 => for문으로 거꾸로 대입해 주고, 마지막에 개행 문자는 따로 선언해 줘야 함.
    // 문자열 함수: #include <string.h> 헤더 선언 필요. 
    
    // (1) strlen(): 문자열 길이 체크(개행문자 제외하고 실제 문자만)
    // (2) strcpy(문자열 배열 A, 문자열 B): strcpy(aa, "XYZ"); => 복사할 문자열의 개행문자 포함 크기로 배열 선언해 둬야 함.
    // (3) strcat_s(문자열 배열 A, 문자열 B), strcat(문자열 배열 A, 문자열 B): 두 문자열 이어주는 함수. 기존 A에 "ABC" 선언되어있었다면 ABCXYZ로 이어져 나오는 것. 기존 배열의 개행문자 없애고 그 자리부터 이어짐.
    // (4) strcmp(A, B): A-B 결과 반환. A자리엔 무조건 배열, B는 문자열, 배열 상관없음. 같은 문자열이면 0 반환. 아스키코드값으로 연산.
    
    // 문자열 입력 gets(), scanf와 유사. 문자열 입력 시 유리. 개행문자 고려해 배열크기-1까지 입력. 엔터 전까지 문자열 받아들임.
    // 문자열 출력 puts(), printf와 유사. 문자열 출력 시 유리. \n 없어도 자동 줄 넘김.
 
    // string.h 라이브러리에 있는 함수 따로 공부해 봐야 함.
 
 
 
    // 9-3) 2차원 배열 => aa[행][열]
    // aa[4차원][면][행][열]
    // 초기화는 행 단위로 중괄호.
 
 
 
    // 예제문제 20) 입력된 문자열 반대로 출력
    char aa[100], bb[100];
    int i;
    
    printf("문자열을 입력하세요 : ");
    gets(aa);
 
    for (i = strlen(aa) ; i >= 0 ; i--) {
        printf("%c", aa[i]);
    }
    printf("\n");
 
 
    // 예제문제 21) 다시 해 보기.
    char aa[100], bb[100];
    int i;
 
    printf("문자 입력: ");
    gets(aa);
    
    printf("변환된 문자: ");
 
    for (i = 0; i <= strlen(aa); i++) { // 65 대문자, 97 소문자, 48 차이
        if (aa[i] >= 'A' && aa[i] <= 'Z') {
            bb[i] = aa[i] + 48;
        }
        else if (aa[i] >= 'a' && aa[i] <= 'z') {
            bb[i] = aa[i] - 48;
        }
        else bb[i] = aa[i];
    }
    bb[i] = '\0';
    printf("%s \n", bb);
 
    
 
 
    
    // 9-4) 배열과 포인터
    // 스택: 한쪽 끝이 막혀서 먼저 들어간 게 나중에 나옴. LIFO(last in first out). 후입선출.
    // (push(데이터 넣는 것), pop(데이터 꺼내는 것), top(가장 마지막에 들어간 데이터 위치))
 
    char stack[5];
    int top = 0;
 
    stack[top] = 'A';
    printf("%c차가 들어감. \n"stack[top]);
    top++;
 
    stack[top] = 'B';
    printf("%c차가 들어감. \n"stack[top]);
    top++;
 
    stack[top] = 'C';
    printf("%c차가 들어감. \n"stack[top]);
    top++;
 
    top--;
    printf("%c차가 나감. \n"stack[top]);
    stack[top] = ' ';
 
    top--;
    printf("%c차가 나감. \n"stack[top]);
    stack[top] = ' ';
 
    top--;
    printf("%c차가 나감. \n"stack[top]);
    stack[top] = ' ';
 
 
    // top이 0일 때 자동차 빼라고 하면 오류. 언더 플로어.
    // 꽉 차 있을 때 더하려고 하면 오류. 오버 플로어.
 
 
 
    // 9-5) 메모리와 주소(원래 메모리는 16진수로 나온다.): 임의의 위치에 4바이트(정수) 자리잡음. 
    int a = 100;
    int b = 200;
    printf("a의 주소는 %d이고, b의 주소는 %d이다. \n"&a, &b);
 
    // 일반 변수는 연달아 저장하지 않음. 배열은 순서대로 저장됨. 시작점을 주소값으로 반환함.(4바이트 == 1바이트 부분)
 
    int aa[3= {10,20,30};
    printf("aa[0] 값은 %d, 주소는 %d이다. \n", aa[0], &aa[0]);
    printf("aa[1] 값은 %d, 주소는 %d이다. \n", aa[1], &aa[1]);
    printf("aa[2] 값은 %d, 주소는 %d이다. \n", aa[2], &aa[2]);
 
 
 
    // 9-6) 포인터 ★★★
    // char* p; 문자형 주소값을 저장하는 변수.
    // int* p; 정수형 주소값을 저장하는 변수.
    // 데이터 타입에 *을 붙이고 변수명 지정해서 선언하는 것이다. 주소값 대입할 변수와 데이터 타입 동일해야 함.
 
 
    char ch = 'A'// 문자형 변수 선언, 값 대입. => ch의 주소는 컴퓨터가 임의로 잡음.
    char* p; // 문자형 주소값 변수 선언. => p의 주소는 임의로 저장, + 포인터는 4바이트.
    p = &ch; // ch('A')의 주소값을 대입한다. => char* p 값이 1031이 아니라 주소를 찾아가서 'A'가 나오는 것.
 
    printf("ch가 가지고 있는 값: %c \n", ch);
    printf("ch의 주소값: %d \n"&ch);
    printf("p가 가지고 있는 값: %d \n", p); // 저장된 주소값만 가지고 올 때는 그냥 포인터 변수명만.
    printf("p가 가진 실제 값: %c \n"*p); // 저장된 주소값의 원래 값을 가지고 오려면 변수명 앞에 *
 
 
    char ch;
    char* p;
    char* q;
 
    ch = 'A';
    p = &ch;
 
    q = p;
 
    *= 'Z'// 그냥 q라고만 적으면 안 바뀜.
 
    printf("ch의 값은 %c이다. \n", ch);
 
 
    // 포인터 완벽하게 이해해야 한다. 
 
 
 
    // 9-7) 배열과 포인터의 관계    
}
cs