티스토리 뷰

c언어

[c언어] 더블포인터, 연산자 우선순위 등

열혈허슬러 상추님 2019.06.20 19:50
190612 (3일차) - 더블포인터, 연산자 우선순위 등
 

교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.

main.c
0.01MB

 
#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 = &ap;
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;
	}
}

 
과제 : 회문인지 아닌지 판단하는 코드.
댓글
댓글쓰기 폼
네이버 이웃추가
«   2019/10   »
    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    
글 보관함