C#/닷넷에서 자주 사용되는 get, set 키워드에 대해서 알아보자.

아주 편리한 키워드 이다.


우선 아래 코드를 보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class People
{
    public String name;
    public int age;
}
 
class Program
{
    static void Main(string[] args)
    {
        People kim = new People();
        kim.name = "kim";
        kim.age = 10;
    }
}
cs


name과 age 변수에 대해서 public으로 설정하여 어디서든 접근이 가능하다.

하지만 이렇게 하면 정보은닉 원칙에 어긋나기 때문에 private 바꾸는 것이 좋다.


그러면 아래와 같이 get과 set 함수들을 만들어 사용할 수 있다. 


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
class People
{
    private String name;
    private int age;
    public String getName() {
        if (name == null)
            return "Error";
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        People kim = new People();
        kim.setName("test");
        kim.setAge(10);
        Console.WriteLine(kim.getName() + " " + kim.getAge());    
    }
}
cs


위와 같은 방식이 이전 java나 C++에서 사용하던 방식들이다.



하지만 C#에서는 좀더 편리한 get, set 키워드를 제공한다.


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
class People
{
    private String name;
    private int age;
    public String Name
    {
        get {
            if (name == null)
                return "Error";
            return name;
        }
        set {
            name = value;
        }
    }
    public int Age
    {
        get {
            return age;
        }
        set {
            age = value;
        }
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        People kim = new People();
        kim.Name = "test";
        kim.Age = 10;
        Console.WriteLine(kim.Name + " " + kim.Age);
    }
}
cs



위의 코드와 같이 private으로 변수를 선언하고 get,set용 프로퍼티를 만들수도 있지만

아래의 코드와 같이 변수 선언을 생략할 수도 있다. (C# 3.0 이후부터 지원)

코드가 좀더 간결해진다.


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
class People
{
    public String Name
    {
        get {
            if (Name == null)
                return "Error";
            return Name;
        }
        set {
            Name = value;
        }
    }
    public int Age
    {
        get;set;
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        People kim = new People();
        kim.Name = "test";
        kim.Age = 10;
        Console.WriteLine(kim.Name + " " + kim.Age);
    }
}
cs



Posted by 꿈만은공돌
,

C# 7.0에서 out 키워드를 좀더 사용하기 쉽게 변경되었다.

기존엔 변수선언을 하고 인자를 전달해야 했지만 C# 7.0 부터는 선언과 동시에 값을 전달 할 수 있도록 변경되었다.


아래 예제를 보자.

기존에 out 키워드를 사용하는 방식이다.

class TtestClass
{
	public void outTest(out int a)
	{
		a = 10;
	}
}
class Program
{
	static void Main(string[] args)
	{
		TtestClass t = new TtestClass();
		int b; //선언을 먼저 해주어야 한다.
		t.outTest(out b);
		Console.WriteLine("b : " + b);
	}
}	


아래는 C# 7.0에서 변경된 방식이다.

class TtestClass
{
	public void outTest(out int a)
	{
		a = 10;
	}
}
class Program
{
	static void Main(string[] args)
	{
		TtestClass t = new TtestClass();
		t.outTest(out int b); //선언과 동시에 인자 전달
		Console.WriteLine("b : " + b);
	}
}


Posted by 꿈만은공돌
,

Visual Studio 2017 C#/.NET 패키지인 NuGet 을 추가하는 방법에 대해서 알아보겠다.

Nuget 패키지 사이트 소개 : http://hijuworld.tistory.com/17

다양한 패키지가 있지만 그중에 C# 7.0에서 지원하는 Tuple 패키지를 추가하는 예제이다.



1. C# 빈 프로젝트를 생성한다.



2. 솔루션 탐색기 탭에서 프로젝트에 종속성을 선택하고 오른쪽 버튼을 클릭 -> NuGet 패키지 관리 클릭




3. 찾아보기 -> System.valueTuple 검색 -> 패키지 선택 -> 설치





4. 변경 내용 미리 보기 에서 확인 클릭 




5. 설치 내역 출력화면에서 확인




6. 예제를 작성하여 테스트


using System;

namespace TestAddTuple
{
	class Test
	{
		public (int id, string name, bool isMan) getInform()
		{
			return (id: 3, name: "홍길동", isMan: true);
		}
	}
    class Program
    {
        static void Main(string[] args)
        {
			Test t1 = new Test();
			var people = t1.getInform();
			Console.WriteLine("id : " + people.id);
			Console.WriteLine("name : " + people.name);
			if(people.isMan)
				Console.WriteLine("man");
			else
				Console.WriteLine("woman");
		}			
    }
}


- 출력 결과 -

id : 3

name : 홍길동

man

계속하려면 아무 키나 누르십시오 . . .




참고 서적 : 크로스 플랫폼 개발을 위한 C# 7과 닷넷 코어 2.0 (에이콘 출판사)


Posted by 꿈만은공돌
,

C#, 닷넷에서 readonly 키워드와 const 키워드는 비슷하지만 다른 키워드 이다.

두 키워드의 차이점 및 공통점에 대해서 알아보자. 


 const 키워드는 대부분에 프로그래밍 언어에서 지원하는 기본적인 문법입니다. 변수를 선언할때 변수 타입앞이나 뒤에 명시하여 해당 변수를 상수화 합니다. 그래서 선언할때 변수값을 지정하면 이 변수는 이제 상수가 되어 값을 읽을 수는 있지만 수정이 불가능 합니다. 이런 불편한 상수를 왜 사용할까 하지만 많은 장점이 존재 합니다. 


 예를들어 원에 넓이를 구하는 문제에서 파이값을 3.14로 해서 파이값 X 반지름 X 반지름 해서 넓이를 구하는 문제에서 파이값은 항상 같기 때문에 변수에 넣어두고 사용하면 됩니다. 하지만 실수로 파이값에 다른 숫자나 변수를 대입하여 값이 변경되면 에러가 발생하게 됩니다. 그래서 파이변수를 선언할 때 const 키워드를 넣어서 상수화 합니다. 그러면 절대 변경될 일이 없기때문에 안정적인 프로그램이 됩니다. 혹시라도 값을 대입하는 코드를 작성하면 컴파일 단계에서 에러가 발생하기 때문에 쉽게 버그를 수정할 수 있습니다. 

 그리고 파라미터로 객체의 주소값을 받으면 해당 객체를 수정하지 못하게 파라미터 선언에 const 키워드를 붙이면 해당 함수에서 파라미터로 넘어온 값을 수정할 수 없게 됩니다. const 키워드를 사용해도 되는 곳이라면 최대한 많이 사용하는 것이 안정적인 코드를 작성하는 방법 입니다. 



1. 공통점


두 키워드 모두 한번 값이 정해지면 수정을 할 수 없다.



아래 두 예제를 보자.

두 예제 모두 클래스에 string 변수를 선언해서 const 키워드를 사용하였다. 해당 test 변수는 상수가 되어서 선언한 곳 이외에서는 수정이 될 수 없다.

혹시라도 수정하려고하면 컴파일 에러가 발생하게 된다.


- const 예제

class TEST
{
	private const string test = "test1234";
	public string getTest()
	{
		return test;
	}
}

class Program
{
	static void Main(string[] args)	
	{
		TEST t1 = new TEST();
		Console.WriteLine("t1 : " + t1.getTest());
	}
}


- readonly 예제

class TEST2
{
	private const string test = "test1234";
	public string getTest()
	{
		return test;
	}
}

class Program
{
	static void Main(string[] args)	
	{
		TEST2 t2 = new TEST();
		Console.WriteLine("t2 : " + t2.getTest());
	}
}



2. 차이점


const키워드와 readonly 키워드의 가장 큰 차이점은 const와는 다르게 readonly 는 생성자에서 값을 초기화 할 수 있다. 아래 예제를 보자. 생성자를 통해 readonly 값을 수정하는 것을 볼 수 있습니다.


- readonly 예제

class TEST
{
	public readonly string test = "start";
	public TEST()
	{
		test = "abc";
	}
	public TEST(string s1)
	{
		test = s1;
	}
}
class Program
{
	static void Main(string[] args)
	{
		TEST t1 = new TEST();
		TEST t2 = new TEST("def");
		Console.WriteLine("t1 : " + t1.test);
		Console.WriteLine("t2 : " + t2.test);
	}
}


test는 readonly 선언을 하였고 초기화를 하였지만 생성자인 TEST()와 TEST(string s1)에서 다시 초기화를 하고있다.

const 선언을 하면 에러가 발생하게 된다.


그리고 const는 선언과 동시에 static이 컴파일러에 의해 자동으로 붙게된다. 정적 필드가 되는것이다. 하지만 readonly의 경우 그렇지 않기 때문에 선언적으로 static 키워드를 붙여주면 정적 필드로 사용이 가능하다.


확장성이 좋고 생성자에 따른 값도 변경할 수 있다. 되도록 const 키워드 이외에 readonly 키워드를 사용하는 것이 좋다.


주의할점은 아래코드와 같이 함수에 지역변수에는 readonly 키워드를 사용할 수 없다.







Posted by 꿈만은공돌
,

C와 C++에서 직접 new 연산자와 malloc 함수를 이용해서 힙(heap)영역에 동적 메모리 할당을 받고 delete 연산자와 free 함수를 이용해서 동적 메모리를 해제하게 된다.


C, C++에서 메모리 할당과 해제 원리 : http://hijuworld.tistory.com/28


하지만 C#과 JAVA 에서는 가비지 컬렉터(garbage collecter)에 의해서 메모리 할당과 메모리 해제가 이루어진다.


사용하지 않는 메모리를 가비지 컬렉션(garbage collection)이 해제 시킨다.


우선 간단하게 메모리를 할당하는 방식에 대해서 알아 보자.




1. C#에서 객체 생성시 메모리 할당 방식

new 키워드를 통해 객체를 생성하게 되면 힙(Heap) 메모리 영역에 객체가 할당된다. C언어와 C++과 다른점은 메모리 첫영역부터 차례대로 할당하게 되고 할당이 가능한 부분의 첫 주소에 포인터로 가르키게 된다. 다음에 또 객체를 생성하면 할당 가능한 메모리의 포인터 영역부터 메모리를 할당하고 다시 해당 포인터는 할당된 사이즈 만큼 증가하게 됩니다.


C, C++과 다르게 이렇게 하면 메모리 할당이 가능한 영역을 찾는 과정이 없기 때문에 속도가 훨씬 빠르다.

아래 그림을 보면 쉽게 이해가 갈것이다.








2. C#에서 Garbage Collector에 의한 메모리 해제 방식

Test a = new TEST();

a = null;

위와 같은 코드를 만나면 처음에 할당한 변수 a가 가지고 있는 객체는 더이상 사용하지 않기 때문에 메모리 해제의 대상이 됩니다.

힙영역에 메모리가 계속 쌓이다 보면 특정 시점에서 Garbage collector에 의해 사용되지 않는 메모리(아래 그림에서 B, D)는 해제하게 된다.

Root Reference 메모리 영역에서 사용하는 메모리 영역을 관리하게 되고(아래 그림의 A와 C) 객체에서 할당한 객체도 존재(아래 그림에서 E)한다. Root Reference를 탐색하여 A와 C를 찾고 다시 A와 C를 검색하여 E를 찾아낸다.

그러면 그외에 메모리 영역인 B와 D는 사용하지 않는 메모리 영역으로보고 메모리를 해제한다.

그리고 남은 A, C, E를 다시 재배치 한다.

그리고 다음 객체를 할당할 메모리의 포인터의 위치도 재배치 한다.




여기까지가 간단하게 설명한 메모리 할당 및 해제 원리이다.

사실 가비지 컬렉션에 방식은 이외에도 상당히 복잡하다.


1. 세대별 가비지 컬렉션 방식 : http://hijuworld.tistory.com/41


2. 용량이 큰 객체에 메모리 할당 해제 방식 : http://hijuworld.tistory.com/46


3. 가비지 컬렉션의 모드에 따른 방식


따라서 이 3가지 방식에 대해서 다음 포스팅에서 설명하겠다.




참고 사이트 및 서적 

- c# GC.Collect() 정리 : http://helloit.tistory.com/40

- 유경상의 닷넷 블로그 : http://www.simpleisbest.net/post/2011/04/01/Review-NET-Garbage-Collection.aspx

- MSDN : https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals

- 뇌를 자극하는 C# 4.0(한빛미디어, 박상현 지음)





Posted by 꿈만은공돌
,


프로젝트를 할때 함수별 또는 클래스 별로 단위 테스트를 진행하고 문제가 있는지 검증을 해보면 좀더 완성도 높은 프로그램을 만들 수 있다.


Microsoft Visual Studio 2017에서 이런 단위 테스트를 어떻게 하는지 알아보자.


클래스를 만들어 그에 속한 함수들을 검증해보는 단위 테스트 프로젝트를 만들어 보자.


1. 파일 -> 새로 만들기 -> 프로젝트 선택




2. Visual C# -> .NET Standard -> 클래스 라이브러리(.NET Standard) -> 라이브러리 이름 지정 -> 확인 클릭






3. 클래스의 이름을 원하는 이름으로 변경하기




4. 아래와 같은 확인창이 뜨면 예(Y) 클릭 




5. 라이브러리에 클래스와 코드를 작성 -> Ctrl + s 로 저장



- 코드 -

using System;

namespace AddLib
{
    public class AddClass
    {
		public double double_add(double a, double b)
		{
			return a + b;
		}
		public int int_add(int a, int b)
		{
			return a * b; //테스트를 위해 오타 작성
		}
	}
}



이제 위에서 작성한 코드를 테스트 하는 단위 테스트 프로젝트를 만들자


1. 파일 추가 -> 추가 -> 새 프로젝트




2. visual C# -> NET Core -> xUnit 테스트 프로젝트 선택 -> 프로젝트 이름 입력 -> 확인 클릭 




3. 단위 테스트 프로젝트에 이전에 작성한 클래스를 추가한다. 

솔루션 탐색기 -> 단위 테스트 프로젝트에 종속성 -> 참조 추가




4. 이전에 테스트용으로 만든 프로젝트 추가




5. 단위테스트 프로젝트에 테스트 코드 작성



- 코드 -


using System;
using Xunit;
using AddLib; //추가
namespace XUnitTestProject1
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {
			double a = 3;
			double b = 4;
			double expected = 7;
			var calc = new AddClass();
			var actual = calc.double_add(a, b);
			Assert.Equal(expected, actual);
		}
		[Fact]
		public void Test2()
		{
			int a = 3;
			int b = 4;
			int expected = 7;
			var calc = new AddClass();
			var actual = calc.int_add(a, b);
			Assert.Equal(expected, actual);
		}
	}
}


6. 단위 테스트 시작

테스트 -> 창 -> 테스트 탐색기




7. 테스트 탐색기 -> 아래 그림과 같이 테스트 실행




8. 아래와 같이 테스트 결과 확인

예상한대로 한개의 에러가 발생하였다.



참고 : 크로스 플랫폼 개발을 위한 C# 7과 닷넷 코어 2.0(에이콘) 서적



Posted by 꿈만은공돌
,

Microsoft Visual studio 2017 C# 빈 콘솔 프로젝트 생성하는 방법이다.



1. 파일 -> 새로 만들기 -> 프로젝트 클릭 







2. Visual C# -> .NET Core -> 콘솔 앱(.NET Core) 선택 -> 프로젝트 이름 입력 -> 확인 선택





3. 코드 입력 -> Ctrl + F5 로 컴파일 및 실행



Posted by 꿈만은공돌
,

Microsoft Visual studio 2017 에서 빈 콘솔 프로젝트 생성하여 Hello world 를 화면에 출력 하는 방법 이다.

c와 C++ 모두 방법은 동일하며 5번에서 파일 선택시 파일 확장자를 .c 로 생성하면 c언어 코드를 작성할 수 있다.



1. 파일 -> 새로만들기 -> 프로젝트 클릭





2. Visual C++ -> Windows 데스크톱 선택 -> Windows 데스크톱 마법사 선택 -> 

   프로젝트 이름 입력 -> 확인

(Windows 콘솔 응용 프로그램 선택시 빈프로젝트로 만들 수 없음)







3. 빈프로젝트 체크, 미리컨파일된 헤더, SDL 검사 체크 해제 -> 확인 클릭





4. 새로은 프로젝트가 생성

   오른쪽 에 소스파일에 오른쪽 버튼 클릭 -> 추가 -> 새항목 선택





5. 왼쪽에서 Visual C++ 선택 -> C++ 파일 선택 -> 파일이름 입력 -> 추가 클릭





6. 코드를 입력 -> Ctrl + F5로 컴파일 및 실행 



Visual studio 2017에서 주의해야 할 점은 scanf 함수를 사용할 때 에러가 발생하여 컴파일이 안될수도 있다.


scanf 함수가 보안상 이슈가 있어서 사용을 못하게 하는 것인데 해당 문제는 아래 링크를 잠고하자.


Visual studio 2017에서 Scanf 사용시 에러가 날때 : http://hijuworld.tistory.com/47






추가로 Visual studio 2017 에서 코드를 자동 정렬 시켜서 보기 좋게 만드는 방법을 소개한 링크이다.


Visual studio 2017 자동 서식 : http://hijuworld.tistory.com/11


아래는 Visual studio 2017 에서 C# 프로젝트를 만드는 방법을 소개한 링크이다.


Visual studio 2017 C# 프로젝트 만들기 : http://hijuworld.tistory.com/10

Posted by 꿈만은공돌
,

C언어와 C++에서는 new 연산자와 malloc 함수를 이용해서 힙(heap)영역에 동적 메모리 할당을 받고 delete 연산자와 free 함수를 이용해서 동적 메모리를 해제하게 된다.


heap 영역에 메모리를 할당하게 되면 자유메모리 블록 리스트(Free memory block list)로 관리가 된다.


새로운 메모리를 할당 할 때에는 자유메모리 블록 리스트를 참고하여 필요한 만큼의 메모리를 할당 할 수 있는 공간을 찾는다.


찾으면 자유 메모리 블록 리스트에 추가하고 할당한 해당 메모리 공간을 초기화 시킨다.


아래 그림을 보면 쉽게 이해가 될 것이다.



처음 malloc(7000); 으로 7000바이트에 메모리를 할당받는다.

가장 첫번째 A영이있는 앞부분부터 탐색을 시작하여 사용하지 않는 메모리를 찾습는다.

B구역이 사용하지 않는 메모리이지만 크기가 4k밖에 안되게 때문에 계속탐색을 하여 가장 뒷부분인 E영역에 할당을 하게 된다


그리고 free(C) 로 C블록을 메모리를 해제시킵니다. 그러면 C영역에 5000바이트의 메모리가 해제가 된다..

이때 malloc(5000) 으로 메모리를 다시 할당하게 된다.

A부터 해서 다시 빈메모리영역을 찾습니다. G영역이 9k가 비어있기 때문에 앞쪽부터 5000바이트에 메모리를 할당 한다.


이런방식으로 계속 메모리 할당과 해제를 계속 하다보면 메모리 단편화가 일어날 수 있다.

메모리를 할당과 해제를 계속하다보면 중간중간 사용하는 메모리와 사용하지 않는 메모리가 존재하게 되된다. 

아래그림처럼 사용하는 메모리와 사용하지 않는 메모리가 있는데 여기서 300바이트가 넘는 메모리를 할당요청하게 되면 할당이 실패하게 된다. 전체 사용하지 않는 메모리는 850바이트나 되지만 단편화가 일어나서 메모리 할당에 실패하게 된다.



메모리 단편화를 피하려면 메모리를 너무 자주 할당 해제하는 것을 피하는 것이 좋다.


그리고 이와 같은 메모리 할당 방식은 앞에서 부터 빈 메모리영역을 탐색하기 때문에  Heap 메모리 영역을 탐색하는데 많은 시간이 소요될 수 있다. 특히 메모리 크기가 크고 빈 메모리영역이 뒷쪽에 있다면 매번 메모리 할당에 오버헤드가 발생한다.


그리고 할당만 하고 해제를 하지 않으면 메모리가 낭비될 수 있다.


사용자가 직접 해제를 시켜줘야하기 때문에 많은 주의가 필요하다.


이런 사용자가 직접 메모리를 할당하고 해제하는 방식과 반대로 가비지 컬렉터가 사용하지 않는 메모리를 자동으로 해제하는 방식에 가비지 컬렉션이라는 방식이 존재한다.

C++ 이후에 등장한 대부분에 언어에서는 이런 가비지 컬렉션을 사용한다. 예를들면 JAVA, C#, GO 언어 들이 가비지 컬렉션을 사용한다.


C#/.NET 가비지 컬렉션의 메모리 할당 및 해제 기본 원리 : http://hijuworld.tistory.com/32


Posted by 꿈만은공돌
,

포인터 배열(Array of Pointer)배열 포인터(Pointer to Array)는 비슷해 보이지만 많은 차이점이 있다.


기본적으로 포인터와 배열에 개념을 정확하게 이해해야 아래 내용을 이해하기 쉽다.


간단히 설명하자면 둘다 비슷한 속성을 가지고 있지만 배열은 메모리공간을 사용자 마음대로 접근하며 데이터를 넣고 수정할 수 있다.


포인터 같은 경우에는 특정 메모리에 주소값을 가지고 있어서 간접참조를 하는 방식이다.


쉽게 이해가 안가면 기본서를 참고해서 공부하는 것이 좋다.


배열 포인터와 포인터 배열 말장난 같지만 가장 쉽게 구분하는 방식은 앞에 붙은 단어는 수식어이고 뒤에 단어가 명사이다.


바나나우유, 딸기우유가 있으면 우유인데 딸기나 바나나가 첨가된 우유이다.


포인터 배열은 주소값들을 저장하는 배열 이다.


배열 포인터는 배열의 시작주소값을 저장할 수 있는 포인터 이다.



- 포인터 배열- 


char *data[] = {"가나다", "ABC", "포인터"};


의 경우 연산자 우선순위에 따라 뒤에 붙은 []이 우선이고 그다음 char *가 그 다음이다.


따라서 data 변수는 배열이다. 그리고 그 배열에 char *를 담는다.


"가나다" 문자열에 시작주소 값을 data[0] 에 넣고


"ABC" 문자열에 시작주소 값을 data[1] 에 넣는다.



아래는 사용 예제 이다. 위에 그림을 코드화 한 것이다. data는 포인터 배열로 char *를 저장하는 배열이다. 그래서 for문을 사용하여 해당 배열들을 탐색하며 값을 출력하는 것을 알 수 있다. data 배열의 사이즈는 명시하지 않았지만 오른쪽에 데이터 갯수를 보고 컴파일러가 알아서 3을 넣게된다.

char *data[] = {"가나다", "ABC", "포인터"};

int i;

for (i=0;i<3;i++) {
    printf("%s\n",data[i]);
}

- 출력 결과 -

가나다

ABC

포인터





 위와같이 포인터 배열은 문자열등과 같이 큰 길이에 데이터들을 포인터로 가르키게하고 해당 포인터들을 다시 배열로 묶어서 관리하기 쉽게 할때 사용하면 좋다. 위와같이 문자열 여러개를 각각 포인터가 가르키게하고 그 포인터들을 하나의 배열로 묶어서 관리해서 사용하기도 쉽고 가독성도 좋다. 만약에 따로따로 하나의 char* 로 할당을 했다면 for문을 사용하기도 힘들었을 것이다.


- 배열 포인터 -


char arr[3][7] = {"가나다", "ABC", "포인터"};

char (*data)[7];

data = arr;


의 경우 (*data) 가 먼저이고 char [7]가 그 다음이다.


따라서 data는 포인터 이다. 포인터는 주소값을 저장하는 곳이다. 따라서 char [7] 자료형에 주소값을 담는다.



data는 char [7]의 주소값을 가지기 때문에 data + 1을 하면 주소값이 sizeof(char) * 7 증가한 메모리의 주소 값을 가진다.  아래 그림과 같다.



아래는 사용 예제 이다. 위에 그림을 코드화 한것이다. arr은 2차원 배열로 문자열들을 할당하고 data는 배열 포인터이다. char [7]을 의 포인터를 가르키는 역활을 한다. 

char arr[3][7] = {"가나다", "ABC", "포인터"};
char (*data)[7];

data = arr;

int i;

for (i=0 ; i<3 ; i++) {
    printf("%s\n", *(data+i));
}


- 출력 결과 -

가나다

ABC

포인터


 배열 포인터는 보통 함수선언을 해서 2차원 배열의 데이터를 파라미터로 받을때 많이 사용한다. 위의 예제에서 처럼 2차원으로 선언한 배열이 있다면 이것을 배열 포인터로 가리키게 하여 접근할 수 있다.

 한가지 주의해야 할 점은  위의 예제에서 처럼 data 입장에서는 arr이 몇개의 데이터를 가지고 있는지 알 수 없다. 그래서 함수에 넘겨줄때에는 3개의 char [7]의 데이터가 존재한다는 사실을 알려주기 위해 추가에 파라미터 변수가 필요하다. 그래야 안정적인 코드작성이 가능하다.

 포인터라는 개념을 공부할 때에는 이해가 가는것 같지만 나중에 실전에서 내가 선언한 배열이나 포인터등을 다른함수에 넘겨주고 다시 반환하는 등에 과정에서 많이 어려워하는 경우가 많다.  


- 참고 사이트 : http://www.soen.kr/

Posted by 꿈만은공돌
,