C프로그래밍...도와주세요

bluesky034의 이미지

배열 90도 회전 코드입니다.
(스크롤바 밑으로...)쭈~욱

#include <stdio.h>
 
void select(int n, int (*p1)[4], int (*p2)[4]);
void change(int (*ptr1)[4], int(*ptr2)[4]);
 
 
int main(void)
{
 
	int arr1[4][4]={
		{ 1, 2, 3, 4},
		{ 5, 6, 7, 8},
		{ 9,10,11,12},
		{13,14,15,16}
	};
	int arr2[4][4];
	int i, j;
	int k;
 
	while(1)
	{
		printf("선택 : 정변환(1), 역변환(2), 종료(3)");
		scanf("%d", &k);
 
		if(k==3)
			break;
 
		select(k, arr1, arr2);
 
	}
 
	printf("\n");
 
	return 0;
 
}
 
void select(int n, int (*p1)[4], int(*p2)[4])
{
	void (*fptr1)(int(*)[4], int(*)[4]);
	int i,j;
 
 
	printf("변형 전 \n");
 
	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
			printf("%2d ", p1[i][j]);
		printf("\n");
	}
 
	printf("\n");
 
	if(n==1)
	{	
		fptr1=change;
		fptr1(p1, p2);
	}
	else if(n==2)
	{
		fptr1=change;
 
		for(i=0; i<3; i++)
		{
			fptr1(p1, p2);
		}
	}
 
	printf("변경 후\n");
 
	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
			printf("%2d ", p2[i][j]);
		printf("\n");
	}
	printf("\n");
 
}
 
void change(int(*ptr1)[4], int(*ptr2)[4])
{
 
	int i,j;
 
	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
		{
			if(i==0)
				ptr2[j][3]=ptr1[i][j];
 
			if(j==3)
				ptr2[3][3-i]=ptr1[i][3];
 
			if(i==3)
				ptr2[3-j][0]=ptr1[3][3-j];
 
			if(j==0)
				ptr2[0][i]=ptr1[3-i][0];
		}	
	}
 
 
 
 
	ptr2[1][2]=ptr1[1][1];
	ptr2[2][2]=ptr1[1][2];
	ptr2[2][1]=ptr1[2][2];
	ptr2[1][1]=ptr1[2][1];
 
	for(i=0; i<4; i++)
	{
		for(j=0; j<4; j++)
		{
			ptr1[i][j]=ptr2[i][j];
		}
	}
 
}

void change(int*(*ptr1)[4], int*(*ptr2)[4])

위의 함수에서 ptr1은 p1을 인자로 받고 있습니다.
void select(int n, int (*p1)[4], int (*p2)[4])

위의 함수에서 p1은 싱글 포인터인데요,

그러니까 ptr1은 더블포인터여야 하지 않나요?

그런데..

void change(int(*ptr1)[4], int(*ptr2)[4])

위의 함수 처럼 싱글 포인터로 실행해도 정상적인 결과를 보입니다.

근데 두 경우 정상 작동 합니다.

irondog의 이미지

배열 포인터[Pointer of Array)는 배열 자체를 포인팅하고 있습니다.
더블포인터를 쓸 이유가 없죠.

배열 포인터는 보통 다음과 같이 선언 합니다.

int a2[3][4];
int a3[2][3][4];
int (*poa2)[4];
int (*poa3)[3][4];

bluesky034의 이미지

처음 arr1[4][4]배열이 싱글포인터 p1에 전달되고...
이 싱글포인터 p1이 ptr1으로 다시 전달 되는데...

싱글 포인터는 더블포인터로 받고
더블 포인터는 트리플포인터로 받고...
이렇게 생각했는데...
그럼 이게 아닌 건가요?
아니면 처음에 배열 이름을 인자로 받아서 예외적인건가요? 그러면 배열이름을 인자로 받은 경우 무조건 싱글포인터를 사용한다라고 생각해야하나요?(배열을 가리키는 경우)

irondog의 이미지

Quote:
싱글 포인터는 더블포인터로 받고
더블 포인터는 트리플포인터로 받고...

네, 보통 공식처럼 이렇게 생각하기 쉬운데 그렇지 않습니다.
포인터를 더블 포인터로 처리하는 이유를 알면 이해가 되리라고 봅니다.

포인터값(주소값)이 변할 수 있는 경우를 가정해 봅시다.
malloc()로 할당된 메모리 주소를 갖고 있는 포인터들이 몇 개 있을 때,
free()후 재할당을 하면 주소값이 변하겠죠. 그럼 이 메모리 주소를 포인팅하는 변수들 모두를 바꿔줘야 하는데, 이렇게 번거롭게 하느니 이럴 때 더블 포인터를 쓰는 겁니다.

그럼 free()후에 재할당 받더라도 이를 더블 포인터로 포인팅하고 있는 변수들은 걱정 할 필요가 없게 됩니다. 더블 포인터를 통해 주소값의 주소값을 갖고 있기 때문에 변화된 주소값을 포인팅 해주고 있는 주소값을 통해 알 수 있기 때문입니다.

질문하신 소스는 이미 배열 포인터가 정확히 배열을 가리키고 있고, 이 값이 변할 걱정을 할 이유가 없기에 배열 포인터를 포인팅할 필요가 없는 경우겠죠.

bluesky034의 이미지

정리하면...

포인터의 포인팅 대상을 바꾸려는 코드가 없는 경우 그냥 포인터로 받아도 괜찮다.
포인터의 포인팅 대상을 바꾸려는 코드가 있는 경우 더블 포인터로 받는다.

꼭 이런 걸 생각할 필요 없이, 더블포인터를 쓰면 위의 두 문장을 포함하기 때문에 공식화가 되었다라고 생각하면 되겠죠 ?ㅎㅎ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.