190612 (3일차) - 더블포인터, 연산자 우선순위 등
교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.
#include <stdio.h>
#pragma warning (disable:4996)
int main() {
int arr[3] = { 1,2,3 };
int*p = arr;
printf("%d\n", *(p++));
printf("%d\n", *(p++));
printf("%d\n", *(p++));
return 0;
}
1
2
3
#include <stdio.h>
#pragma warning(disable : 4996)
int main()
{
int arr[3] = {1, 2, 3};
int *p = arr;
printf("%d\n", *(p++));
printf("%d\n", *p++);
printf("%d\n", *(p++));
return 0;
}
위와 동일
(*p)++ , ++*p 는 값자체를 변경한다.
11
|
22
|
33
|
44
|
55
|
p가 11을 가리키고 있을 때
*p++ : 22
*(p+1) : 33
++*p : 23
*p+1 : 24
(*p)++ : 23 (후위:->24)
*++p : 33
*p+=1 : 34
# f 문자 전까지 출력하기.
#include <stdio.h>
#pragma warning(disable : 4996)
void put_s(char *);
int main()
{
char arr[] = "abcdefghijklmnopqrstuvwxyz";
put_s(arr); // arr? char형 배열이구나!!!
return 0;
}
void put_s(char *p)
{
// 'f' 문자가 나오기 전까지만 출력하시오.
while (1)
if (*p != 'f')
printf("%c", *p++);
else
break;
}
#끝 까지 출력
#include <stdio.h>
#pragma warning(disable : 4996)
void put_s(char *);
int main()
{
char arr[] = "abcdefghijklmnopqrstuvwxyz";
put_s(arr); // arr? char형 배열이구나!!!
return 0;
}
void put_s(char *p)
{
// 'f' 문자가 나오기 전까지만 출력하시오.
while (1)
if (*p != '\0')
printf("%c", *p++);
else
break;
}
# strcpy를 구현해보자
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void my_strcpy(char *target, char *src)
{
//printf("src size %d\n", strlen(src));//4
int length = strlen(src);
for (int i = 0; i < length; ++i)
{
*(target + i) = *(src + i);
}
*(target + length) = '\0';
}
int main()
{
char buff[10], src[10] = "abcd";
//strcpy(buff, src);
my_strcpy(buff, src);
puts(buff);
return 0;
}
#간략화.
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void my_strcpy(char *dst, char *src)
{
while (*dst++ = *src++)
;
}
int main()
{
char buff[10], src[10] = "abcd";
//strcpy(buff, src);
my_strcpy(buff, src);
puts(buff);
return 0;
}
-> 널문자(\0)도 0으로 해석된다. 즉 조건에서 alse 로 인식한다.
#나만의 strcat
void my_strcpy(char *dst, char *src)
{
while (*dst++ = *src++)
;
}
void my_strcat(char *dst, char *src)
{
int length = strlen(dst);
while (*(dst++ + length) = *src++)
;
}
int main()
{
char buff[10], src[10] = "abcd";
//strcpy(buff, src);
my_strcpy(buff, src);
puts(buff);
my_strcat(buff, "xyz");
puts(buff);
return 0;
}
#또는
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void my_strcpy(char *dst, char *src)
{
while (*dst++ = *src++)
;
}
void my_strcat(char *dst, char *src)
{
while (*dst)
*dst++;
while (*dst++ = *src++)
;
}
int main()
{
char buff[10], src[10] = "abcd";
//strcpy(buff, src);
my_strcpy(buff, src);
puts(buff);
my_strcat(buff, "xyz");
puts(buff);
return 0;
}
#strcmp (문자열 비교)
# 이중 포인터
# swap
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
int main()
{
int tmp;
int a = 10, b = 5;
int *pa, *pb;
int **ppa, **ppb;
pa = &a;
pb = &b;
ppa = &pa;
ppb = &pb;
tmp = **ppa;
**ppa = **ppb;
**ppb = tmp;
printf("a:%d b:%d \n", a, b);
return 0;
}
# 바꾸고 출력하기
int main()
{
int a;
int *p;
int **k;
p = &a;
k = &p;
*p = 10;
printf("%d \n", a);
**k = 20;
printf("%d \n", a);
return 0;
}
#더블포인터사용
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
connect(int *a, int **p)
{
*p = a;
}
int main()
{
int a = 7;
int *p;
connect(&a, &p);
printf("%d\n", *p); //7
return 0;
}
#포인터 문제
#include <stdio.h>
#include <string.h>
#pragma warning (disable:4996)
void swap(int*a, int*b) {
int temp = *a;
*a = *b;
*b = temp;
}
// ap,bp 변수의 주소를 전달받아 a,b값을 교환하는 함수
void swap2(int**ap, int**bp) {
int temp = **ap;
**ap = **bp;
**bp = temp;
}
// app, bpp 변수의 주소를 전달받아 a,b 값을 교환하는 함수
void swap3(int ***app, int***bpp) {
int temp = ***app;
***app = ***bpp;
***bpp = temp;
}
// ap,bp변수의 주소를 전달받아 ap,bp값을 교환하는 함수
void swap4(int**ap, int**bp) {
int* tmp = *ap;
*ap = *bp;
*bp = tmp;
}
// app, bpp 변수의 주소를 전달 받아 ap, bp 값을 교환하는 함수
void swap5(int***app, int***bpp) {
int* tmp = **app;
**app = **bpp;
**bpp = tmp;
}
// app,bpp 변수의 주소를 전달받아 app,bpp값을 교환하는 함수
void swap6(int ***app, int***bpp) {
int** tmp = ***app;
***app = ***bpp;
***bpp = tmp;
}
int main() {
int a = 10, b = 20;
int *ap = &a, *bp = &b;
int **app = ≈
int **bpp = &bp;
//printf("변경전 a:%d b:%d \n", a, b);
//swap2(&ap, &bp);
//swap3(&app, &bpp);
//printf("변경후 a:%d b:%d \n", a, b);
//printf("변경전 a:%d b:%d \n", *ap, *bp);
//swap4(&ap, &bp);
//swap5(&app, &bpp);
//printf("변경후 a:%d b:%d \n", *ap, *bp);
//printf("변경전 a:%d b:%d \n", **app, **bpp);
//swap6(&app, &bpp);
//printf("변경후 a:%d b:%d \n", **app, **bpp);
return 0;
}
#포인터 배열
#2차원 배열을 가리키는 포인터
void main()
{
int(*p)[3]; // int형 3개짜리 배열을 가리키는 포인터
int *p[3]; // 인트형 포인터가 3개짜이 있는 포인터 배열
int a[2][3];
int b[5][3];
p = a;
p = b;
}
a[1][2] == *(a[1]+2) == *(*(a+1)+2) == (*(a+1))[2]
___________ : *( (a[0] +1)+2 )
싱글포인터
|
배열포인터
|
포인터배열
|
int a[2][2];
int *p;
p=a[0];
|
int a[2][3];
int (*p)[3];
p=a;
|
int a[2][3];
int *p[2];
p[0] = a[0];
p[1] = a[1];
|
|
|
|
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
//2차원 배열을 2차원 처럼 처리
void array_2d(int (*p)[3])
{
p[0][0] = 10;
}
//2차원 배열을 1차원 처럼 처리
void array_1d(int *p)
{
p[0] = 10;
}
void main()
{
int a[2][3];
array_2d(a);
array_1d(a[0]);
}
#ex
#ex2
시스템쪽 가면 메인함수의 매개변수는 필수로 알아야한다.
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
void put_p(char **p)
{
puts("// abcd를 출력하는 여러구문");
printf("%s\n", p[0]);
printf("%s\n", *p);
puts("// sert를 출력하는 여러구문");
printf("%s\n", p[1] + 2);
printf("%s\n", *(p + 1) + 2);
printf("%s\n", &p[1][2]);
printf("%s\n", &(*(p + 1))[2]);
puts("// m를 출력하는 여러구문");
printf("%c\n", p[2][2]);
printf("%c\n", *(*(p + 2) + 2));
printf("%c\n", *((p[2]) + 2));
printf("%c\n", (*(p + 2))[2]);
}
void main(int argc, char **argv)
{
char *p[3] = {"abcd", "insert", "home"};
put_p(p);
}
// abcd를 출력하는 여러구문
abcd
abcd
// sert를 출력하는 여러구문
sert
sert
sert
sert
// m를 출력하는 여러구문
m
m
m
m
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
&a + 1 은 총블럭 만큼 이동함.
★★★★★★★★★★
a+1 => 한 행 건너뜀
a[0]+1 => 한 원소 건너뜀
a[0][0] + 1 => 원소 자체에 숫자 1을 더함
&a+1 => 총 블럭크기 만큼 건너 뜀
&a[0]+1 => 한 행 건너뜀
&a[0][0]+1 => 한 원소 건너뜀
*a == a[0]
*(a+1) == a[1]
★★★★★★★★★★
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void main()
{
int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
puts("===[3][4] 값 들===");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; ++j)
{
printf("%3d ", a[i][j]);
}
puts("");
}
puts("===[3][4] 주소들===");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; ++j)
{
printf("%x ", &a[i][j]);
}
puts("");
}
printf("01. a : %x \n", a);
printf("02. *a : %x \n", *a); // 2차원 배열에 1차원 배열에 해당하는 이름
printf("03. a[0] : %x \n", a[0]);
printf("04. *a[0] : %x \n", *a[0]);
printf("05. (*a)[0] : %x \n", (*a)[0]);
printf("06. *(*(a+1)+0) : %x \n", *(*(a + 1) + 0));
printf("07. (*(a+1))[0] : %x \n", (*(a + 1))[0]);
printf("08. *(*(a+0)+2) : %x \n", *(*(a + 0) + 2));
printf("09. (*a + 2)[0] : %x \n", (*a + 2)[0]);
printf("10. (*(*a)+1) : %x \n", (*(*a) + 1));
printf("11. &(a+1)[2] : %x \n", &(a + 1)[2]);
printf("12. *a+1 : %x \n", *a + 1);
printf("13. (a + 1)[2] : %x \n", (a + 1)[2]);
printf("14. &(*a)[0] : %x \n", &(*a)[0]);
printf("15. a[1]+2 : %x \n", a[1] + 2);
printf("16. &*(*(a+2)) : %x \n", &*(*(a + 2)));
printf("17. *a+1 : %x \n", *a + 1); // 2차원 배열에 1차원 배열에 해당하는 이름
printf("18. a[0]+1 : %x \n", a[0] + 1); // 2차원 배열에 1차원 배열에 해당하는 이름
printf("19. a+1 : %x \n", a + 1); // 2차원 배열에 1차원 배열에 해당하는 이름
}
===[3][4] 값 들===
1 2 3 4
5 6 7 8
9 10 11 12
===[3][4] 주소들===
12ffca0 12ffca4 12ffca8 12ffcac
12ffcb0 12ffcb4 12ffcb8 12ffcbc
12ffcc0 12ffcc4 12ffcc8 12ffccc
01. a : 12ffca0
02. *a : 12ffca0
03. a[0] : 12ffca0
04. *a[0] : 1
05. (*a)[0] : 1
06. *(*(a+1)+0) : 5
07. (*(a+1))[0] : 5
08. *(*(a+0)+2) : 3
09. (*a + 2)[0] : 3
10. (*(*a)+1) : 2
11. &(a+1)[2] : 12ffcd0
12. *a+1 : 12ffca4
13. (a + 1)[2] : 12ffcd0
14. &(*a)[0] : 12ffca0
15. a[1]+2 : 12ffcb8
16. &*(*(a+2)) : 12ffcc0
17. *a+1 : 12ffca4
18. a[0]+1 : 12ffca4
19. a+1 : 12ffcb0
# 배열 내부에문자열을 뒤집어주는 strrev 함수
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void my_strrev(char *arr)
{
for (int i = 0; i < strlen(arr) / 2; ++i)
{
char tmp = arr[i];
arr[i] = arr[strlen(arr) - 1 - i];
arr[strlen(arr) - 1 - i] = tmp;
}
}
void main()
{
char arr[] = "aabcc";
my_strrev(arr);
puts(arr);
}
# 거꾸로 뒤집어서 주어진 수만큼 반복해서 더하기
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void my_strrev(char *arr)
{
for (int i = 0; i < strlen(arr) / 2; ++i)
{
char tmp = arr[i];
arr[i] = arr[strlen(arr) - 1 - i];
arr[strlen(arr) - 1 - i] = tmp;
}
}
void main()
{
int repeat;
int num;
printf("입력: ");
scanf("%d", &num);
scanf("%d", &repeat);
for (int i = 0; i < repeat; ++i)
{
printf(" %d\n", num);
char str[100];
itoa(num, str, 10);
my_strrev(str);
int revNum = atoi(str);
printf("+ %d\n", revNum);
puts("----------");
printf(" %d\n\n", num = num + revNum);
}
}
# 인자로 계산식 받아서 계산하기
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)
void main(int argc, char *argv[])
{
// 3 + 20
// 23호출
if (argc < 4)
return;
printf("%s\n\n", argv[1]);
if (argv[2][0] == '+')
{
int a = atoi(argv[1]), b = atoi(argv[3]);
printf("%d + %d = %d", a, b, a + b);
}
int a = atoi(argv[1]), b = atoi(argv[3]);
switch (argv[2][0])
{
case '+':
printf("%d + %d = %d", a, b, a + b);
break;
case '-':
printf("%d - %d = %d", a, b, a - b);
break;
case '*':
printf("%d * %d = %d", a, b, a * b);
break;
case '/':
printf("%d / %d = %d", a, b, a / b);
break;
case '%':
printf("%d % %d = %d", a, b, a % b);
break;
}
}
과제 : 회문인지 아닌지 판단하는 코드.
'c언어' 카테고리의 다른 글
[c언어] 자료구조, sort 등 (0) | 2019.07.01 |
---|---|
[c언어] 구조체, 파일입출력, 전처리기지시자 등 (0) | 2019.07.01 |
[c언어] 함수포인터, typedef, 전처리기 지시자, malloc 등 (0) | 2019.06.21 |
[c언어] 싱글포인터, 배열 등 (0) | 2019.06.19 |
[c언어] 비트연산자, 삼항연산자, 열거형(enum), 함수 등 (0) | 2019.06.17 |