1. 포인터(주소값)
포인터 변수
포인터 상수(배열) : 값을 변경하기 위해서는 strcpy() 필요
변수 : 값을 담기 위한 저장공간
포인터 변수 : 주소값을 담기 위한 저장 공간
포인터 변수를 줄여서 포인터라고 부르기도 한다.
2. 포인터를 사용하는 이유
1) return값은 반드시 한 개여야 하기 때문에 포인터를 사용한다.
주소값은 유일하기 때문에(중복이 없기 때문에)
주소값을 다른 영역에 전달하면 (참조로 접근해서)값을 수정할 수 있다.
3. 포인터 확인하는 방법
1) 중단점 : F9
2) 디버그 : F5
3) 디버그클릭 > 창 > 자동 > 주소값 우클릭 > 값 복사 클릭
4) Ctrl + Alt + m, 1 : 메모리1 창
5) 주소 붙여넣기
6) 다음 줄 디버깅 : F10
4. 이중 포인터
: 포인터의 주소값을 담기 위해 사용한다.
다른 영역에 있는 포인터의 값을 수정하기 위해 사용한다.
5. 포인터 배열
: 포인터를 여러 개 선언하게 되면 관리가 힘들기 때문에
포인터 형식의 배열을 선언할 때 사용한다.
6. 배열 포인터
: 배열의 주소값을 담을 저장공간
7. 오늘 실습코드
1) cafe 만들기
** cafe.c **
#include<stdio.h>
#include<string.h>
//사용자 정의 헤더파일 추가
#include"twosomeplace.h"
//상품 최대 개수
#define CNT 100
/*전역변수*/
//상품명 배열
char arName[CNT][100] = { "", };
//가격 배열
int arPrice[CNT] = { 0, };
//추가된 상품 총 개수
int insertCnt;
//검색된 상품의 행번호
int rowNum;
void main() {
//twosomeplace.h 참고
cafe();
}
** twosomeplace.h **
#define CNT 100
/*======함수 선언부======*/
/*재사용의 목적*/
char checkDup(char[]);
void insert(char[], int);
void update(char[], int, int);
void delete();
int select(char[], int[]);
/*소스코드 간결화*/
void printInsert();
void printUpdate();
void printDelete();
void printSelect();
void selectAll();
void cafe();
/*================*/
//extern 사용시 초기값을 넣을 수 없다.
//중복 선언으로 간주된다.
extern char arName[CNT][100];
extern int arPrice[CNT];
extern int insertCnt;
extern int rowNum;
void cafe() {
char title[20] = "♨Twosome place♨";
char menu[100] = "①추가하기\n②수정하기\n③삭제하기\n④검색하기\n⑤목록보기\n⑥나가기\n";
char errMsg[20] = "다시 시도해주세요.";
int choice = 0;
while (1) {
printf("%s\n%s", title, menu);
scanf_s("%d", &choice);
if (choice == 6) { break; }
switch (choice) {
//추가
case 1:
printInsert();
break;
//수정
case 2:
printUpdate();
break;
//삭제
case 3:
printDelete();
break;
//검색
case 4:
printSelect();
break;
//목록
case 5:
selectAll();
break;
//그 외
default:
printf("%s", errMsg);
}
}
}
//중복검사
char checkDup(char temp[]) {
//외부에서 문자열을 전달받아서 arName에 있는지 없는지 검사
char check = '0';
for (int i = 0; i < insertCnt; i++) {
if (!strcmp(arName[i], temp)) {
rowNum = i;
//중복이 있다면 check는 '1'
check = '1';
break;
}
}
return check;
}
//추가
//char insert(char temp[], int price) {
void insert(char temp[], int price) {
//char isDup = checkDup(temp);
//char check = '0';
//if(!(isDup - 48)){
//외부에서 중복검사 진행 후 insert()사용!
strcpy_s(arName[insertCnt], sizeof(arName[insertCnt]), temp);
arPrice[insertCnt] = price;
//총 상품개수 1 증가
insertCnt++;
//check = '1';
//}
//return check;
}
void printInsert() {
char isDup = ' ';
char temp[100] = "";
int price = 0;
printf("상품명 : ");
scanf_s("%s", temp, sizeof(temp));
isDup = checkDup(temp);
//중복이 없다면 참
//문자 - 48 == 정수
if (!(isDup - 48)) {
printf("가격 : ");
scanf_s("%d", &price);
insert(temp, price);
}
else {
printf("중복된 상품명입니다.\n");
}
}
//수정
void update(char temp[], int price, int choice) {
//외부에서 새로운 상품명, 새로운 가격, 수정할 상품의 행번호를 전달 받는다.
strcpy_s(arName[choice], sizeof(arName[choice]), temp);
arPrice[choice] = price;
}
void printUpdate() {
char temp[100] = "";
char isDup = ' ';
int choice = 0;
int price = 0;
printf("수정하실 기존 상품명 : ");
scanf_s("%s", temp, sizeof(temp));
isDup = checkDup(temp);
//수정할 상품이 있는지(1번), 있다면 새로운 상품명이 중복되는지(2번)
//총 checkDup()를 2번 사용하기 때문에 1번 rowNum을 기억해야 한다.
//1번 rowNum이 수정할 행 번호이기 때문이다. 따라서 choice에 1번 rowNum을
//저장한다.
//만약 저장하지 않으면 2번에서 rowNum의 값이 변경될 수 있다.
choice = rowNum;
//1번
if (isDup - 48) {
printf("새로운 상품명 : ");
scanf_s("%s", temp, sizeof(temp));
isDup = checkDup(temp);
//2번
if (!(isDup - 48)) {
printf("새로운 가격 : ");
scanf_s("%d", &price);
update(temp, price, choice);
}
else {
printf("중복된 상품명입니다.\n");
}
}
else {
printf("수정하실 상품이 존재하지 않습니다.\n");
}
}
//삭제
void delete() {
for (int j = rowNum; j < insertCnt; j++) {
strcpy_s(arName[j], sizeof(arName[j]), arName[j + 1]);
arPrice[j] = arPrice[j + 1];
}
insertCnt--;
}
void printDelete() {
char temp[100] = "";
char isDup = ' ';
printf("삭제할 상품명 : ");
scanf_s("%s", temp, sizeof(temp));
isDup = checkDup(temp);
if (isDup - 48) {
delete();
}
else {
printf("삭제하실 상품이 존재하지 않습니다.\n");
}
}
//검색
int select(char temp[], int arIdx[]) {
//상품명, 검색된 상품의 행번호를 담을 배열의 주소를 전달받는다.
int cnt = 0;
for (int i = 0; i < insertCnt; i++) {
//arName의 각 요소에 temp가 포함되어 있다면 검색 성공!
//"아" 검색시 "아"가 포함된 모든 문자열 검색
if (strstr(arName[i], temp) != NULL) {
//결과가 한 개 이상이 나올 수 있기 때문에 arIdx를 배열로 만든다.
//i는 검색된 상품의 행 번호이다.
arIdx[cnt] = i;
cnt++;
}
}
//총 검색 결과 건수 리턴
return cnt;
}
void printSelect() {
char temp[100] = "";
int arIdx[100] = { 0, };
int cnt = 0;
printf("검색할 상품명 입력 : ");
scanf_s("%s", temp, sizeof(temp));
//이 영역에 있는 arIdx의 주소를 select함수에 전달한다.
cnt = select(temp, arIdx);
for (int i = 0; i < cnt; i++) {
//arIdx배열은 각 방에 검색된 상품의 행 번호를 가지고 있다.
//따라서 순서대로 cnt만큼 반복하면 검색 결과를 출력할 수 있다.
printf("%s(%d원)\n", arName[arIdx[i]], arPrice[arIdx[i]]);
}
//검색 결과가 없을 때
if (cnt == 0) {
printf("검색결과 없음\n");
}
}
//목록
void selectAll() {
char temp[100] = "";
strcpy_s(temp, sizeof(temp), insertCnt == 0 ? "목록 없음" : "상품명(가격)");
printf("%s\n", temp);
for (int i = 0; i < insertCnt; i++) {
//총 상품 개수만큼 순서대로 출력
printf("%s(%d원)\n", arName[i], arPrice[i]);
}
}
2) pointerTest.c
#include<stdio.h>
void main() {
int data = 10;
int data2 = 20;
int* PData = &data;
PData = &data2;
printf("%d\n", data);
printf("%d\n", *PData);
printf("%p\n", &data2);
printf("%p\n", PData);
}
3) pointer.c
#include<stdio.h>
void function(int data) {
data = 100;
}
void function2(int* pData) {
*pData = 100;
}
void main() {
int data = 10;
//call by value : 값에 의한 호출
function(data);
printf("%d\n", data);
//call by address : 주소값에 의한 호출
function2(&data);
printf("%d\n", data);
}
4) pointerTask.c
#include<stdio.h>
//정수를 입력받고 입력받은 정수의 제곱을 구해주는 void형 함수 선언하기
//main()함수에서 정수를 입력받는다.
void 제곱(int* PNum) {
*PNum = *PNum * *PNum;
}
void main() {
int num = 0;
printf("정수 : ");
scanf_s("%d", &num);
printf("%d의 제곱 : ", num);
제곱(&num);
printf("%d\n", num);
}
5) doublePointer.c
#include<stdio.h>
//void function(int* pData) {
void function(int** PPData) {
int data = 100;
//pData = &data;
*PPData = &data;
}
void main() {
int data = 10;
int* PData = &data;
//function(pData);
function(&PData);
printf("%d\n", *PData);
}
6) poterEtc.c
#include<stdio.h>
#define L 3
void main() {
int arData[L] = { 10, 20, 30 };
int(*arPData)[L] = &arData;
for (int i = 0; i < L; i++) {
//printf("%d\n", (*arPData)[i]);
printf("%d\n", *((*arPData) + i));
}
//int* PArData[L] = { 0, };
//for (int i = 0; i < L; i++) {
// PArData[i] = &arData[i];
//}
//for (int i = 0; i < L; i++) {
// printf("%d\n", *PArData[i]);
//}
}
'웹_프론트_백엔드 > 단과' 카테고리의 다른 글
[단과_C] 2020.03.20 (0) | 2020.03.22 |
---|---|
[단과_C] 2020.03.19 (0) | 2020.03.20 |
[단과_C] 2020.03.17 (0) | 2020.03.18 |
[단과_C] 2020.03.16 (0) | 2020.03.17 |
[단과_C] 2020.03.13 (0) | 2020.03.15 |