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 토실토실천재
2010. 7. 10. 02:05
제 17장 포인터의 이해 - 예제

포인터에 대한 이해가 단번에 되기란 쉽지가 않습니다.
그렇기 때문에 예제를 몇개 올려서 여러분께서 직접 실행을 해보면서
이해를 하시기 바랍니다.


에제 1)

#include <stdio.h>

int main()
{
char c = 'B'; // 변수선언
int i = 19;
float f = 4.5f;

// & 연산자를 앞에 붙여줌으로써 주소값을 반환하게 한다.
// 주소를 printf함수로 십진수형태로 출력을 한다.

printf("c의 주소 = %d \n", &c);
printf("i의 주소 = %d \n", &i);
printf("f의 주소 = %d \n", &f);

return 0;
}


에제 2)

#include <stdio.h>

int main()
{
 
// 포인터 변수를 선언 방법 
// int a;
// int *p = &a; // ( int a; int *p; p = &a); 와 같은 표현이다.
// p를 포인터 선언하자 마자, a를 가리키게 한다.

// int type
int i = 300; // 선언한 변수와
int *pi = &i; // 포인터 변수를 선언시 둘의 타입이 같아야한다.
// pi는 i의 메모리주소를 값으로 가지고 있다.
// pi 는 i를 가리킨다로 표현한다.
//char type
char c = 'C';
char *pc = &c;

// short int type
short s = 32;
short *ps = &s;

printf("i = %d \n", i);
printf("*pi = %d \n\n", *pi);
// *pi : pi가 가르키는 변수의 값을 나타냄, 즉, i의 값 300 을 나타냄
printf("c = %c \n", c);
printf("*pc = %c \n\n", *pc);

printf("s = %d \n", s);
printf("*ps = %d \n\n", *ps);

return 0;

}



에제 3)

#include <stdio.h>

int main()
{
int a = 123;
int* p = &a; // int *p;
// p = &a;

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

*p = 456; // p가 가리키는 변수의 값을 456으로 하겠다

printf("*p = 456; \/\/ 실행후 \n");
printf(" a = %d \n", a);
printf("*p = %d \n", *p);

return 0;
}


에제 4)

#include <stdio.h>

int main()
{
int i = 0x12345678; // 16진수형태
char *pc = (char*) &i;
// char형의 포인터 변수가 int형의 변수를 가리킨다
// 포인터와 변수 형을 맞추기 위해서 캐스팅연산을 해준다.

printf("i = %d \n", i);
// 10진수형태로 i의값을 출력

printf("*pc = %d \n", *pc);
// 값을 출력하면 120이 나오는데
// 120이 나온이유는 0x78 의 값이 10진수형태로 나오게 된것이다.
// 보통은 메모리값을 읽을때 뒤에서 부터 읽기때문에
// char 포인터 pc의 첫번째 주소는 0x78을 가리킨다.
// 자세한 사항은 댓글을 적어주시는분께 설명 드리겠음
return 0;
}


에제 5)

#include <stdio.h>

int main()
{
int a  = 100;

int* p = &a;

int* pp = &p; // 포인터를 가리키는 포인터
printf("   a = %d \n", a); // a값 출력 : 100
printf("  *p = %d \n", *p); // p가 그리키는 a의 값 출력 : 100
printf("  &a = %d \n", &a); // a의 메모리주소값 출력
printf("  &p = %d \n", &p); // p의 주소값이 출력
printf(" *pp = %d \n", *pp); // pp가 가리키는 변수의 값 출력

return 0;


}

에제 6)

#include <stdio.h>

int main()
{
int a = 200;
int *p = NULL; // NULL : 0값을 가진 변수
// 현재 p가 가리키는 값은 없다
if(NULL!=p) // 만약 p의 값이 0이 아니라면
*p = 30;


p = &a; // p는 a의 주소를 가진다(p는 a를 가리킨다)

if(!p) // if(NULL!=p) 같은 의미다
*p = 30;

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

return 0;
}


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

제 19장 포인터의 이해 - 예제분석  (0) 2010.07.10
제 18장 포인터의 이해 - 2  (0) 2010.07.10
제 16장 포인터의 이해 - 1  (0) 2010.07.10
제 15장 1차원 배열 - 2  (0) 2010.07.10
제 14장 1차원 배열 - 1  (0) 2010.07.10
Posted by 토실토실천재
2010. 7. 10. 02:04


제 16장 포인터의 이해 - 1

※ 프로그램은 눈과 손이 아닌....그림과 말로 이해하는 습관으로!


포인터와 포인터 변수

 - 포인터는 변수이다(포인터 변수) : 상수가 될수 있긴함

 - 메모리의 주소값을 저장하기 위한 변수 ==> 포인터를 한다

 - 주소값과 포인터는 다른 의미임

 - 메모리구조를 항상 생각하면서 프로그램 하는 습관을 기르자!


   메모리구조(포인터)


#include <stdio.h>
{
char c = 'a';
int n = 7;
double d = 3.14;
....


↓↓↓


변수 c의 주소는 뭘까요? => 0x1000
변수 n의 주소는 뭘까요? => 0x1001
변수 d의 주소는 뭘까요? => 0x1005

 ☞ 변수의 주소는 주소의 시작번지로 표현된다.

참고 > 당신의 컴퓨터는 몇 bit 시스템인가요?
 -> bit수가 클수록 시스템의 성능은 좋아진다.
 -> 결정적인 bit가 정해지는 이유?? 

@ 즉, 8bit 시스템은 메모리의 주소값이 8자리로 표현된다.
  ex) 0001 0001, 0010 0001

  32비트면 32자리로 표현된다.(2의 32승, 즉 4G 까지 메모리 사용가능)
  그러므로 주소번지개수를 많이 만들수 있다

  8 비트 시스템은 포인터의 크기는 1바이트
  16비트 시스템은 포인터의 크기는 2바이트
  32비트, 64비트 시스템은 포인터가 최하 4바이트가 된다.(32bit = 4byte)

  pn이라는 n의 값을 가르킨다.

  
 


 포인터의 타입과 선언

 - * : 포인터 선언시사용되는 연산자

 - P형 포인터(P*) : P형(data type) 변수의 주소값을 지정
  > int 형 포인터 : int * p ;              // int형 변수를 가리키는 포인터
  > double 형 포인터 : double * lp; // double형 변수를 가리키는 포인터
  > char 형 포인터 : char * ch;      // char형 변수를 가리키는 포인터 

  ex) int* a;
      int * a;
      int *a;   // 이 3가지 다 똑같다.
  

 
주소관련 연산자

 - & 연산자 : 변수의 주소 값 반환(번지 연산자 / 주소연산자)

 - * 연산자 : 포인터가 가리키는 메모리 참조
예제)=============================================================   

#include <stdio.h>

int main()
{
int a = 200;
int *pA = &a;  // &a : a라는 변수의 주소값을 반환하라
// a의 주소값을 pA에 저장하라
// pA의 포인터는 a를 가리킨다
printf("%d \n", a);  // 직접접근
printf("%d \n", *pA);  // 간접접근

// pA자체만 출력한다면, a의 주소값을 출력할거다
// *pA : pA 변수가 가르키는 변수를 뜻함, 즉 a

return 0;
}

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

#include <stdio.h>

int main()
{
int a = 100;
int *pA = &a;

printf("pA : %d \n", pA);
printf("&a : %d \n", &a);

(*pA)++; // pA가 가리키는 변수 a의 값을 1 증가시킨다.

printf("a   : %d \n", a);
printf("*pA : %d \n", *pA);

return 0;
}

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

※(참고) * 용도 

1. 곱셈용도   
2. 포인터 선언   (int *p : p라는 int형 포인터 선언)
3. 포인터를 접근 (*p : p라는 포인터가 가르키는 변수의 값)
 

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

제 18장 포인터의 이해 - 2  (0) 2010.07.10
제 17장 포인터의 이해 - 예제  (0) 2010.07.10
제 15장 1차원 배열 - 2  (0) 2010.07.10
제 14장 1차원 배열 - 1  (0) 2010.07.10
제 13장 C언어의 핵심 함수 - 3  (0) 2010.07.10
Posted by 토실토실천재