2019. 1. 24. 08:59
우선은 C#을 하기 위해서는 닷넷 프레임워크가 깔려있다면
어디서 작성을 해도 좋으나
풍부한 편의성과 개발자 편의를 위해서 Visaul  Studio 2005 버전이상에서
작성하는것이 좋습니다. 물론 2008이 현재까지는 제일 좋습니다.
해당 글을 작성된 일자가 꾀 오래되었네요..양해바랍니다.

현재는 마이크로소프트사에 가면 Visual Studio Community 버전이 있으므로 
무료로 사용할 수 있습니다^^

그리고 시중의 C#책...본인도 그리 많이 본것은 아니지만, 대부분 C/C++과 비교설명한것이 
대부분이더군요. 순수하게 C#을 가지고만 접근한책이 많이 부족합니다. 그래서 처음 하신분들은
짜증이 날지도 모르지만, 어쩔수없습니다. 본인은 C/C++을 공부해본적이 있기때문에,
그리고 본인도 부족하지만 C를 가르친 경험도 있어서, C가 더 편합니다.
C#자체가 C/C++에 모태를 두고 있기 때문에 개발자들과 역자들은 어쩔수없이 비교설명하고, 대부분 C/C++을 했다고 가정을 하기  때문에 짜증이 나더라도 이해해야 할것 같네요. 좀더 고차원적으로
언급하자면, 프로그래밍 언어의 기능은 다 비슷비슷 하다는 생각도 하게 될것입니다.

1. C# 타입 시스템
  - 1. 자동메모리 관리 기능 
        (이에 따라 개발자는 메모리에 대한 접근과, 걱정을 하지 않으셔도 됩니다)
  - 2. 통합 시스템이다 보니 모든것이 객체로 존재 합니다. 어떤 데이타라도 객체로 취급합니다.
  - 3. 프로퍼티, 메서드, 이벤트는 기본으로 제공
  - 4. C#은 어튜리뷰트를 지원하고, 컴포넌트에 대한 정보를 정의 할수 있습니다.

좀 어려운 말을 적었네요. 사실 지금은 그러려니 하면서 넘어가셔도 크게 상관은 없습니다.
그렇다고 무시하고 넘어가란말은 아닙니다. 프로그램을 작성하실때는 메모리에 아주 민감해져야
합니다. 아키텍쳐(닷넷내부실행과정)의 중요성을 지나친다면.........
프로그래머가 아닌 그냥 따라치는 사람이 되어 버립니다.
여기서 미처 언급하지 못한 내용을 여러가지 책을 통해서 습득하셔야 합니다.

2. C#의 첫 발자국 "hello C#" 작성해보기
  - hello.cs
   1. 비쥬얼스튜디오 2008을 켠다. 좀 무거워서 로딩하는데 시간이 걸립니다.
       참고) 로딩 : 느린메모리에서 상대적으로 빠른메모리로 로드하는것을 로딩이라고 합니다.
                - 하드디스크에서 메모리로의 로딩 
                - 메모리에서 캐쉬메모리(cpu)로의 로딩
   2. 메뉴를 보시면 파일 클릭 ->

 
 
 
거기에서 프로젝트 를 켜시면 C#을 선택하셔서
      콘솔응용프로그램을 클릭합니다. 그리고 프로젝트 이름을 쓰시고 확인!

   3. 그럼 기본 코드가 자동으로 나옵니다. 우린 그냥 그 안에 있는것을 다 지우고 해봅니다.
 
 
  - hello.cs

using System;

namespace A
{
    class B
    {
           static void Main()
           {
                   System.Console.WriteLine("hello, C# this is my First C# programing Code");
           }
    }
}

 
자 이렇게 누르시고 Ctrl + F5 키를 누르세요(컴파일 + 실행)
 
 
드디어, 처음으로 C#.NET 응용 프로그램을 작성해보신겁니다.     
좀 감을 잡으셨다면 System.Console.WriteLine.... 안에 글을 적으면 화면에 똑같이
찍히는걸 볼수있습니다.
처음하신분들은 많이 실망하셨을수도 있습니다. 까만 화면에 흰글자....이거 왠지 
윈도우환경에 익숙한지라 허접해 보일수 있겠지만 모든 프로그램의 학습의 기본은 콘솔환경입니다.
콘솔환경 ... 까만 화면에 흰글자...즉, 그래픽이 없는 문자명령체계 라고 ...

하지만 기본 구현학습에 있어서 콘솔환경만큼 좋은곳은 없습니다.
여기에서 잘 하셔야 나중에 현란한 윈도우창도 만들고, 눈으로도 멋진 프로그램을 만들수있으니까요
우린 디자인보다는 우선은 기능을 배워야 합니다.그것도 잘....
 이것저것 찍어보시고 많이 가지고 노시길 바랍니다.

참고로 자동으로 코드가 완성되는 기능이 있는데, 이것에 익숙해지시면 안됩니다.
부디...키보드로 직접 코딩하십시오.

코드에 대한 설명과 컴파일러에 사용은  다음장에 하겠습니다.


내용이 도움이 되었다면 xrp tip 한번^^



'프로그래밍 > C#' 카테고리의 다른 글

C#-7. 객체지향과 클래스  (0) 2019.01.31
C#-6. 데이타 타입  (0) 2019.01.29
C#-4. 컴파일러와 dll파일  (0) 2019.01.25
C#-3. 네임스페이스  (0) 2019.01.25
C#-1. C#의 특징  (1) 2019.01.23
Posted by 토실토실천재
2019. 1. 23. 16:04


C#은 닷넷개발프로그램의 대표적인 언어입니다.
기존 과거에 다른 언어의 단점을 과감히 털어벌이고, 새로운 흐름을 위한 객체지향개념의 언어입니다.

과거에도 여러가지의 언어도 혼합프로그래밍이 가능했으나, 실질적으로 
번거로움이 상당히 많았습니다.
C, 파스칼, 어셈블리의 언어의 오브젝트파일(컴파일된 파일)을 링크시켜서
하나의 실행파일을 만드는것 가능했어요.

하지만 닷넷은 이러한 혼합프로그램이 매우 수월해졌으며, 현재까지 이런 혼합프로그램이 가능한
즉, 닷넷을 지원하는 언어가 60개 정도 된다. 매우 크게 발전했다는 생각이 들기도 하면서,
닷넷의 힘이 느껴지기도 합니다.

1. C#의 특징
   1. 기반언어 : C++, 자바 ==> 고차원적으로 업그레이드
     - 특징
        1. 완벽한 객체지향언어
        2. 편리한 개발자가 사용 편리한 인터페이스 환경
        3. 메모리에 대한 사용자 부담이 없다.(자동 가비지 콜렉션기능)
        4. 타입이 엄격 및 문법이 엄격하다.
        5. 많은 문법의 확장
        6. 닷넷플랫폼의 대표적인 언어로써의 닷넷의 모든 장점을 갖고 있음. 등등등

  2. 프로그램을 한번이라도 해보신분이라면
       1. 특히, C/java를 해보신분들은 어색하지 않는 코드문법입니다.
           즉, java또한 C++을 참고했고, C++은 C의 확장이기 때문에 변수선언방식이나
           함수/메소드 등 특정기능 사용이 비슷합니다.

  3. 처음 프로그램 하신분이라면
       1. 우선적으로 코드기법을 배우는것은 위험합니다.
          - 닷넷의 등장배경, 닷넷의 기능, 닷넷이 추구하는 것등 그리고 프로그램 실행 구조
            를 먼저 파악하는것이 중요합니다. 무엇보다도, 하드웨어에 대한 기초지식이 있다면
            더더욱 좋을거 같네요.

       2. 역시나 책을 좀 많이 보셨으면 합니다. 코드를 친다고 해서 어쩌어찌 되긴 합니다만
          이론을 알고 코딩을 하는것이 훨씬 좋습니다.  처음 부터 결과를 위해서 코드를 작성
          하는것은 훈련하지 않는 달리기 선수가 10초대를 가기를 바라는것과 같습니다.
   


유용하게 보셨다면 xrp로 팁 한번 부탁드립니다.

'프로그래밍 > C#' 카테고리의 다른 글

C#-7. 객체지향과 클래스  (0) 2019.01.31
C#-6. 데이타 타입  (0) 2019.01.29
C#-4. 컴파일러와 dll파일  (0) 2019.01.25
C#-3. 네임스페이스  (0) 2019.01.25
C#-2. C#으로 첫 발자국  (0) 2019.01.24
Posted by 토실토실천재
2010. 7. 10. 02:16

제 25장 다차원 배열

  


※ 포인터, 배열은 무엇인지를...잘 숙지해야 합니다.
    ->> 더블포인터를 위한 공부를 위해서 집중하세요
        >> 포인터 개념이 이해가 안되시면 다시 포인터/배열부분 강의를
              한번 더 공부하고 오시기 바랍니다.


다차원 배열이란? ; 2차원 이상의 배열

 - 배열 선언 예)
   
   int arr[5];             // 1차원 구조
   int arr1[10][6];     // 2차원 구조
   int arr2[4][4][5];  // 3차원 구조

 ※ 2차원배열만 이해를 한다면 나머지 2+n 차원 배열이 이해가 빨라요
    tip => 2차원 이상은 실제 쓰일 경우가 거의 없습니다.

 

 


2차원 배열의 선언

  - 2차원적 메모리를 구성

 

 ex)

 int main()
{
 arr1[4]; 
 arr2[3][4]; // 3은 세로, 4는 가로를 의미라고 생각
                  // 3 X 4 인 배열 선언
 ......           // 배열크기는 3x4(12)x4byte = 48 byte

 return 0;
}

 

예제)=============================================================  

 

/* 2차원 배열 요소의 접근 방법 */

 

#include <stdio.h>

int main()
{
 int arr[3][3];
 arr[0][0] = 1;
 arr[1][0] = 2;
 arr[2][0] = 3;

                                                         
 ....

}     // 참고 : 배열 ; 상수포인터

      // 그림 : 예제이해

 

 

 

예제)=============================================================  


#include <stdio.h>

int main(void)
{
 int Array[4][2];
 int i, j;

 int number;

 for(i=0; i<4; i++)
 {
  for(j=0; j<2; j++)
  {
   printf("%d 층 %d호 인구입력 : ", i+1, j+1);
   scanf("%d", &Array[i][j]);
  }
 }

 for(i=0; i<4; i++)
 {
  number = 0;

  for(j=0; j<2; j++)
  {
   number += Array[i][j];
  }

 printf("%d 층, 총인구 : %d \n", i+1, number);

 }

 return 0;
}

================================================================  

 

 

 

다차원 배열의 실제 메모리 구성
 
 - 접근 방법을 2차원적으로 해석할뿐, 1차원 배열과 동일하다.

 

 - 2차원배열이라고해서 메모리구조는 2차적으로 되는것이 아니다.
    >> 배열선언시 2차원배열선언시, 1차원적인 배열메모리를 생각하세요
 


 - 그림참고(배열선언시 메모리구조의 모습)

 

 

 

2차원 배열 ! 선언과 동시에 초기화

 

 - 방법 1 : 행 단위로 모든 요소들을 초기화

 

 - 방법 2 : 행 단위로 일부 요소들만 초기화
   
 ex 1)

int Array[3][3] = {
 
 {1, 2, 3},
 {3, 4, 5},
 {5, 6, 7}

}


 ex 2)

int Array_1[3][3] = {

{0},       // 나머지 Array_1[0][1], Array_1[0][2]는 0으로 초기화
{1, 2},   // 나머지 Array_1[1][2]는 0으로 초기화 
{4, 5, 6}

}


 ex 3)

int Array_2[3][3] = {1, 2, 3, 4, 5, 6}; // 이렇게 해도 문법적으로 문제 없다


 

초기화 리스트에 의한 배열 크기의 결정

 

 - 1차원 배열의 예
  >> int Array[] = {1, 2, 3}; // 정상 OK

 

 - 2차원 배열의 예
  >> int Array[][] = {1, 2, 3, 4, 5, 6}        // Error!
  >> int Array[][4] = {1, 2, 3, 4, 5, 6, 7, 8} // OK
  >> int Array[][2] = {1, 2, 3, 4, 5, 6, 7, 8} // OK

 

   ===> 두개의 인덱스 모두를 생략할 수는 없다.
           둘 중에 한개의 인덱스만 선언해주면 컴파일러가 자동으로 인덱스를 인식한다.
 


3차원 배열의 선언과 의미

 

  - 3차원적 메모리를 구성(있다는것만 아시면 되요)

 

  - 일반적으로 거의 쓰이지 않는다.(배열과 포인터를 이용하기 위한 용도만...)

 

  - 4차원 이상은 4차원형태이므로 구조적인 이해가 불가

 
 

 
Posted by 토실토실천재
2010. 7. 10. 02:14

 

제 24장 포인터와 함수에 대한 이해 - 2

 

 


Call by Value (call : 함수를 호출한다)

 

 - 값의 복사에 의한 함수 호출
 
 - 가장 일반적인 함수 호출 형태

 

예제)=============================================================  

 

#include <stdio.h>

int Add(int num1, int num2); // 더하기 함수 선언

int main()
{
 int val1 = 100;
 int val2 = 200;
 
 printf("더하기값(Add 함수값) : %d \n", Add(val1, val2));

 return 0;
}

int Add(int num1, int num2) // 더하기 함수 정의
{
 return num1 + num2;
}

// main 함수내의 val1, val2값을
// Add함수에 매개변수에 복사한다는 의미

 

 

 

예제)=============================================================  


#include <stdio.h>

 

void swap(int a, int b);


int main(void)
{
 int number_1 = 10;
 int number_2 = 300;

 printf("number_1 = %d \n", number_1);
 printf("number_2 = %d \n", number_2);

 swap(number_1, number_2);

 return 0;
}

 

void swap(int a, int b)
{
 int temp;

 temp = a;
 a = b;
 b = temp;

 printf("a = %d \n", a);
 printf("b = %d \n", b);

}


// val1, val2의 값이 그대로 복사해서 Add함수의 num1, num2에 전달된다.
// 즉, val1, val2와 num1, num2는 별개의 변수다



================================================================  

 

call by Reference 
 
 - 참조(참조를 가능케 하는 주소값)를 인자로 전달하는  형태의 함수호출

 

예제)=============================================================  

 

#include <stdio.h>

 

void P_add(int* p)      // main함수의 number의 주소값을 인자로 받는다
{
 (*p)++;                     // p는 main함수의 number을 가리키므로 number값이 1증가한다.
}

int main()
{
 int number = 100; 

 P_add(&number);      // number의 주소값을 넘긴다.

 printf("number = %d \n", number);

 return 0;
}

 

================================================================  

 

 

scanf 함수 호출시 &를 붙이는 이유?

 

 - scanf("%d", &val);
   // scanf함수가 val이라는 변수에 접근하기 위해서
   // 주소값을 찾아서 실행된다.(call by reference)

 - scanf("%s", str);
   // 배열이름이 주소값이며, 포인터이름 자체가 주소값 str 이기때문에
   // &를 붙일 필요가 없다.

 

 


포인터가 가리키는 변수의 상수화

 - int a = 20;
   const int* p = &a;
   *p = 10; // Error
   a = 30;  // ok!;
 // p가 a를 봤을때만! a는 상수다
 // p라는 포인터로 a값을 변경 불가능하다!

 

 

 

포인터 상수화

 - int a = 20;
   int b = 100;
   int* const  p = &a;
   p = &b;   // Error
   *p = 30;  // ok!;
// p라는 포인터가 가리키는 값 자체를 상수화
// p는 무조건! 항상 a만 가리킬수 있음.

 - const int* const p = &a 이경우는
   위의 두가지 특징을 다 가진다.
  > p는 무조건 a만 가리키고 p를 통해서 a값을 변강할수 없다.

 

 


const 키워드를 사용하는 이유

 

 - 컴파일시 잘못된 연산에 대한 에러메시지
 
 - 프로그램을 안정적으로 구성

 

 

 

Posted by 토실토실천재
2010. 7. 10. 02:12
제 23장 포인터와 함수에 대한 이해 - 1


call by Reference
call by Value 

이번장은 저 위에 두가지 개념을 확실히 이해합시다!


함수의 인자로 전달하기

 - 값의 복사에 의한 전달 예)

void Fuction(int a) // val의 값을 변수 a에 복사
{
a++;
return a;
}

int main(void)
{
int val = 10; 
val = Function(val); // val이 지니고 있는 값을 전달하는것이다.
return 0;
}                                  // 변수 val, a는 다름(별개의 것)



배열의 인자로 전달하기
 // 배열전체 복사할수 없다(불가능)

 - 배열의 주소값을 전달한다!!

 - 값의 복사에 의한 전달 예제)

예제)=============================================================   


#include <stdio.h>

void Function(int* New_Array);

int main()
{
int Array[5] = {0, 1, 2, 3, 4};        // index값이 5인 배열 Array 선언
int i;

printf("Array배열의 요소 : ");

for(i=0; i<5; i++)
printf("%d ", *(Array + i)); // Array배열을 순서대로 출력

Function(Array);          // Function 함수호출(인자값은 Array의 주소로)
printf("\n배열요소값을 변경후 : ");// Array의 이름자체가 주소라고 인식을 하고 넘어가요

for(i=0; i<5; i++)         // 다시 Array배열 순서대로 출력
printf("%d ", *(Array + i));

printf("\n");

return 0;
}

void Function(int* New_Array) // main함수에서의 Array의 주소값을 받는다.
{           // 배열의 형태도 가리키는 포인터 형태이므로 
int j;          // int* 형식으로 주소값을 받는다!
int temp;

for(j=0; j<3; j++)
{
temp = *(New_Array+j); // 임시변수로 값자체를 바꾼다.
*(New_Array+j) = *(New_Array+4-j);// tip) : *(A+i) == A[i]
*(New_Array+4-j) = temp;
}
}

// Array값의 변경을 Function 함수에서 변경한셈이다.

// 즉, Function 함수가 int*형(int Array[])을 받기 때문에 똑같이 int*형을 선언한뒤
// Array의 주소값을 받는 셈 
// 배열전체자체를 받는건 불가능하다

=================================================================   

배열이름, 포인터 sizeof 연산 

 - 배열이름 : 배열 전체크기를 바이트 단위로 넘김

 - 포인터 : 포인터의 크기(4)를 바이트 단위로 넘김

예제)=============================================================   


#include <stdio.h>

int Sum_Array(int* N_Array, int index);

int main()
{
int Array[8] = {1, 2, 3, 4, 5, 6, 7 , 8};
int Serve_Sum;
printf("index of Array = %d \n", sizeof(Array)/sizeof(int));
Serve_Sum = Sum_Array(Array, sizeof(Array)/sizeof(int));
printf("Sum of Array's factors : %d \n", Serve_Sum);

return 0;
}
// sizeof연산을 이용한 논리적인 인자전달을 한다면
// 코드의 변화시 수정해줄 요소가 적어진다.
// 어떠한 환경에 변화에 따라서 프로그램이 유연하게 동작하도록
// 코딩을 하는것이 최선이다
// int대신 4를 넣어도 되지만, 시스템에 따라서 int는 2, 4, 8 이 인식되기때문에
// sizeof(int)라고 인자전달을 하게 코딩한것임

int Sum_Array(int* N_Array, int index)
{
int i, sum=0;

for(i=0; i<index; i++) // i<index ==> i< sizeof(N_Array) (4가 리턴될뿐)
sum += *(N_Array+i); // sum += N_Array[i]

return sum;
}

=================================================================   


"int * Array" vs "int Array[]"

 - 둘다 같은 의미를 지닌다.

 - int Array[]은 배열보다는 포인터에 가깝다.

 - 매개변수 안에서는 저렇게 사용이 가능 : Array[];(하지만 자제하시오)
 
 - 배열과 포인터 혼돈을 피하기위해서는 int* Array 형태가 더 좋다


Posted by 토실토실천재
2010. 7. 10. 02:11

제 22장 포인터와 배열의 이해! 함께 이해하기 - 2



포인터와 배열을 통해서 얻을 수 있는 중대한 결론

 - arr[i] == *(arr+i); // arr이 "포인터"이거나 "배열이름" 인 경우


예제)=============================================================   

#include <stdio.h>

int main()
{
int Array[2] = {10, 20};

int* pArray = Array;                                // pArray는 배열Array를 가리킨다.

printf("Array[0] = %d \n", Array[0]);       // Array[0]값 출력
printf("*(pArray) = %d \n", *(pArray));     // pArray가 가리키는 값출력
printf("\n");

printf("Array[1] = %d \n", Array[1]);       // Array[1]값 출력
printf("*(pArray+1) = %d \n", *(pArray+1));

// pArray가 가리키는 주소값 4byte만큼 더 증가.. 즉, 다음 배열요소값을 출력
// 4byte를 건너뛰었기때문에 역시나 배열도 자료형을 가진다는 의미이다

printf("*(Array+1) = %d \n", *(Array+1));   // Array[1] == *(Array+1) == *(pArray+1)
return 0;                                                // 배열이름은 포인터닷!
}
// 자 이해못하신분들은 밑에 그림을 보고 이해해볼까요?

그림참고이해)
 

=================================================================   



문자열 표현 방식의 이해

 - 배열 기반의 문자열 변수
 
 - 포인터 기반의 문자열 상수

  > char str1[5] = "abcd"; // 문자열을 담아서 변수다.
  > cahr *str2 = "ASDF";
 
예제)=============================================================   

#include <stdio.h>

int main()
{
char str1[5] = "abcd";
char* str2 = "ASDF";

printf("str1 = %s \n", str1);
printf("str2 = %s \n", str2);

str1[0] = 'k'; // 배열요소의 값을 변경한다.
// str2[0] = 'k' ===> Error!...상수이기때문!

printf("str1 = %s \n", str1);
printf("str2 = %s \n", str2);

return 0;
}
=================================================================   

포인터 배열

 
 - 배열의 요소로 포인터를 지니는 배열

  > int* Array1[10];
    double* Array2[20];
    char* Array3[30];

 

예제)=============================================================   

#include <stdio.h>

int main(void)
{
int a = 10;
int b = 20;
int c = 30;

int* Array[3] = {&a, &b, &c};

printf("*Array[0] = %d \n", *Array[0]);
printf("*ARray[1] = %d \n", *Array[1]);
printf("*Array[2] = %d \n", *Array[2]);

return 0;
}

그림참고이해)

 


예제)=============================================================   

#include <stdio.h>

int main()
{
char* Array[3];

Array[0] = "Today is Good day";
Array[1] = "Someboy call me";
Array[2] = "Konichwa";

// char* Array[3] = {0x1000, 0x2000, 0x3000};

printf("Array[0] = %s \n", Array[0]);
printf("*(Array+1) = %s \n", *(Array+1));
printf("*(Array+2) = %s \n", *(Array+2));

return 0;
}
그림참고이해)

 

Tip) 모든문자열은 선언과 동시에 메모리공간이 올라가고
     그 후 그 문자열의 주소값(첫글자의 주소값)이 리턴된다.

// 매우중요한 내용이므로 절대!!, 꼭 13장 그냥 넘어가면 안됩니다!

Posted by 토실토실천재
2010. 7. 10. 02:09
제 21장 포인터와 배열의 이해! 함께 이해하기 - 1



※ 배열과 포인터의 상관관계를 이해하는 시간을 가져볼까요~


배열의 이름의 정체

 - 배열의 이름 : 첫번째 요소의 주소값을 나타낸다.
                       (0번째 인덱스의 주소값)
 
  ex) &A[0] : "A배열의 0번째 요소의 주소값을 반환하라."

 - "포인터 == 주소값 + 자료형 ( 아주 중요 )"

 - 배열이름도 포인터다. 배열이름 ==>> (상수)포인터

 - 배열이름 : 주소값 + 자료형



배열 이름의 타입

 - 배열이름도 포인터이므로 타입이 존재
 
 - 배열 이름이 가리키는 배열요소에 의해 결정

   ex) int arr1[10] => int*
        double arr2[20] => double*


※ 자, 지금내용부터는 매우 중요하기에 차근차근 읽고 실습해 보자구요


배열 이름의 활용(배열이름도 포인터다, 다만 배열이름은 상수이다)

 - 배열 이름을 포인터처럼, 포인터를 배열 이름처럼 활용하는것이 가능



예제)=============================================================   

#include <stdio.h>

int main()
{
int a[5] = {1, 2, 3, 4, 5}; // 요소개수가 5개인 배열 a를 선언 및 초기화
int* p;                          // 포인터 p를 선언

p = a; // a배열의 이름은 a[0]의 주소값이기때문에 &를 붙일이유가 없다.
         // p라는 포인터가 a를 가리킨다

 
printf("%d %d %d %d %d \n", p[0], p[1], p[2], p[3], p[4]);
printf("%d %d %d %d %d \n", a[0], a[1], a[2], a[3], a[4]);

p = &b;  // 가르키는 값을 변경가능
printf("%d \n", *p);

return 0;
}

 
// a라는 (배열)상수 포인터는 무조건 a[0]만 가리킬수 있어서, 변경불가능
// p는 일반포인터이기 때문에 변경가능함

=================================================================   



 

포인터 연산 : 포인터가 지니는 값을 증가 혹인 감소시키는 연산을 의미한다.
                       ; 포인터가 가리키는 대상의 자료형에 따라서 증가및 감소되는 값이 차이를 지닌다.

ex) ptr++;
    ptr +=3;
    --ptr1;
    ptr2 = ptr1 + 2;

예제)=============================================================   

 
#include <stdio.h>

int main(void)
{
int* ptr1 = 0; // 0번지가 아니고 NULL 포인트 즉, 아무것도 가리키고 있지 않다.
char* ptr2 = 0; // 참고) 별로 좋지 않은 선언이다.
double* ptr3 = 0;

printf("%d번지, %d번지, %d번지 \n", ptr1++, ptr2++, ptr3++);
printf("%d번지, %d번지, %d번지 \n", ptr1, ptr2, ptr3);

return 0;
}

// int형은 4바이트, 4만큼 증가
// char형은 1바이트, 1만큼 증가
// double형은 8바이트, 8만큼 증가

// 그 포인트가 자료형의 따라서 그 증가값이 증가한다.

 

예제)=============================================================   

#include <stdio.h>

int main()
{
int arr[5] = {1, 2, 3, 4, 5};

int* Arr_P = arr;                 // 현재 Arr_P는 a[0]를 가리킴

printf("%d \n", *Arr_P);      // Arr_P가 가리키는 값출력 : 1

printf("%d \n", *(++Arr_P)); // Arr_P의 주속값 4바이트 증가, 그 요소값 출력 : 2
printf("%d \n", *(++Arr_P)); // Arr_P의 주속값 4바이트 증가, 그 요소값 출력 : 3

printf("%d \n", *(Arr_P+1)); // Arr_P의 주속값 4바이트 증가, 그 요소값 출력 : 4
printf("%d \n", *(Arr_P+2)); // Arr_P의 주속값 8(2*4)바이트 증가, 그 요소값 출력 : 5

return 0;
}

그림참고 )

 

// 최종적으로 지금 Arr_P가 가리키는 상태는 3을 가리키고 있다.

Posted by 토실토실천재
2010. 7. 10. 02:06
 제 20장 포인터의 이해 - 그림표현


다음 프로그램을 분석해서 그림을 그려서 표현하세요

#include <stdio.h>

int main()
{
    int val_1 = 100;
    int val_2 = 200;

    int* Point_1 = &val_1;
    int* Point_2 = &val_2;

    printf("*Point_1 = %d \n", *Point_1);
    printf("*Point_2 = %d \n", *Point_2);

    Point_1 = &val_2;    // Point_1은 val_2를 가리키게 한다.
    Point_2 = &val_1;    // Point_2는 val_1를 가리키게 한다.

    printf("*Point_1 = %d \n", *Point_1);
    printf("*Point_2 = %d \n", *Point_2);

    return 0;
}
   

가장 기본적인 포인터 설명은 이것으로 하고 다음시간에는
조금더 고차원(?)적인 강의로 볼게요


 
Posted by 토실토실천재
2010. 7. 10. 02:06

제 19장 포인터의 이해 - 예제분석


예제_1) =================================================================================

#include <stdio.h>
 
int main(void)
{
 
   char a ='a';
   int b = 1;
   float c =1.3f;
   double d =3.5;
// 각 포인트 자료형은 가리키는 자료형에 맞게 선언해줄것을 주의!
   char *p1 = &a; // p1는 a를 가리키고 있다. 
   int *p2 =&b; // p2는 b를 가리키고 있다.
   float *p3 =&c; // p3는 c를 가리키고 있다.
   double *p4 = &d; // p4는 d를 가리키고 있다.
 
   *p1 =*p1+1; // p1이 가리키는 변수의 값에 1을 더한다. a = 'b'
   *p2 =*p2+1; // p2가 가리키는 변수의 값에 1을 더한다. b = 2;
   *p3+=1;                  //*p3=*p3+1과 같다 (p3가 가리키는 변수의 값(c+=1)
   *p4+=1;                  //*p4=*p4+1과 같다 (p4가 가리키는 변수의 값(d+=1)
 
   printf(" a : %c \n", a); // a는 문자기 때문에 아스키코드값이 1증가하면서 b로 된다.
   printf(" b : %d \n", b);  
   printf(" c : %f  \n", c);
   printf(" d : %lf  \n", d);

   return 0 ;
}

예제_2) =================================================================================
 
#include <stdio.h>
 
int main(void)
{
 
   int a = 10;
   int b = 20;
 
   int *p1 = &a;         // 포인터 변수 p1은 a를 가리키고 있다. p1은 a의 주소값을 값으로 가진다.
   int *p2 = &b;         // 포인터 변수 p2는 b를 가리키고 있다. p2는 b의 주소값을 값으로 가진다.
   int *temp; // 포인터 변수 temp 선언만!, 현재 어딘가를 가리키고 있음(쓰레기값을 가짐)
 
  (*p1)--; // p1이 가리키는 변수의 값, 즉 a의 값을 -1 연산을 한다.
  (*p2)--; // p2가 가리키는 변수의 값, 즉 b의 값을 -1 연산을 한다.
 
  // p1과 p2가 가리키는 대상을 서로 변경

  temp = p1; // 포인터변수 temp는 p1의 주소값을 가진다.
  p1=p2; // 포인터변수 p2의 주소값을 p1로
  p2=temp; // 포인터변수 temp의 주소(즉 p1의 주소)를  p2에 대입
 
  printf("%d, %d \n", *p1,*p2); // p1, p2 가 가리키는 주소가 바뀌게 됨
  return 0 ;               
}

포인터 공부는 설명도 설명이지만, 직접 메모리 구조를 그려보면서, 주소값, 변수값 등의
변화등 특징을 공부하시는게 더 이해가 빠를겁니다.
소스만 분석하는게 아니고, 직접 그림을 그려보면서 말로 풀이를 해보면서 해보세요~

포인터 강의자료를 참고하세요~

Posted by 토실토실천재
2010. 7. 10. 02:05

제 18장 포인터의 이해 - 2



포인터에 다양한 타입이 존재하는 이유

 - "포인터 타입참조할 메모리의 크기 정보 제공"

 - 포인터 int* a, char* b,  이 두 포인터변수의 크기는 얼마일까?
    > sizeof연산자를 이용 : printf(" %d byte ", sizeof(a) );

 - 포인터의 크기는 32비트 운영체제에서 무조건 4byte다

 - 주소값을 보관하는 변수이기때문에, 주소값 자체는 4byte;

 - 굳이 왜 포인터에 type를 두느냐??
   > 포인터는 자료형도 같이 기억을 한다. 
   > 메모리값 보관량은 4byte, 어떤 변수든 크기에 상관없다. 


 ※ 포인터는 주소값일까?

 - pointer = 주소값 + 자료형(int*, char*....) 

 - 자료형도 포인터란 개념에 포함되기때문에 
   항상 가르키는 자료형에 맞게 선언을 해줘야 한다.


예제_0)=============================================================   

#include <stdio.h>

int main()
{
int a = 10;
int *pA = &a;     //a는 4byte

double E = 3.14;
double *pE = &E;

printf("%d %f", *pA, *pE);

return 0;
}

예제_1)=============================================================   

int main()
{
int *pA ; // 컴퓨터내, 임의의 어딘가를 가리키고 있다(쓰레기값으로 초기화)
*pA = 10; // 위험한 선언이다.
return 0;
}

예제_2) ============================================================   

#include <stdio.h>

int main()
{
int *pA = 100;  // pA가 가르키는곳이 어딘데 100을 대입하겠다는건가?
// 당연히 이건 오류가 된다.
*pA = 10;
return 0;
}

==================================================================   

위의 예제_1 에서 만약에 pA 포인터변수가 컴퓨터내의 중요한 부분을 가리킬 수 있다.
물론 운영체제가 지금은 너무 좋아져서, 위의 예제는 크게 위험하지 않지만,
그게 허용이 된다면..상당히 위험해진다.
Posted by 토실토실천재