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 토실토실천재
2010. 7. 10. 02:04


제 15장 1차원 배열 - 2



문자열 상수

 - 문자열이면서 상수의 특징을 지닌다.

예) printf("hi, i'm chun jae saim \n");
   // 문자열이 메모리 공간에 먼저 올라간후 printf함수 를 호출한다.
   // 문자열 상수 임; 문자열 데이타는 바꿀수 없다.
   // 이 문자열을 변수로 지정하는 방법? : 배열사용

1. 메모리 공간에 hi, i'm chun jae saim이라는 문자열이 올라간다.
 - 즉 문자열은 상수다.-> " " 안에 문자열은 상수다.

2. 이 메모리값의 주소값이 printf함수로 넘어간다.

3. 실제 주소값을 전달하면서 printf함수가 실행

 ☞ 우리는 이제 문자열을 변수로 선언해보는 작업을 해보자



●  문자열 변수 

 - 문자열이면서 변수의 특징을 지닌다.

 ex) char array[5] = "Good"

//  한 요소에 한 문자를 넣는다
//  근데 문자열의 길이는 4인데 배열요소는 5개이다.
 
 ex) char array_1[] = "Evening";
  
  // 오른쪽에 있는 문자열의 데이타를 참조해서 즉, 7개
  // 하지만 문자열의 길이는 7 + 1로 해준다.

  문자열 배열이라고 한다.(문자열 변수)
  
예제) ======================================================

 #include <stdio.h>

int main()
{
char Array[6] = "Hello";       // 문자열길이 5+1개  
char Array_1[8] = "morning"; // 문자열길이 7+1개

printf("%s \n", Array);  // 문자열형태 %s
printf("%s \n", Array_1);

return 0;
}

// 과연 왜 +1을 해줘서 표현을 하는건지?

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

 문자열의 특징

 - 문자열 ; C언어에서는 문자열 조건
  > 반드시 NULL문자를 가진다.
  > NULL을 달아줘야 하는 이유?
   
 - 문자열은 (NULL)문자를 끝에 지닌다.

 - 널(NULL)문자 : '\0'(숫자 0임)
                  (아스키코드 값으로 0); 

 ex) char arr[] = "AB" // []안에는 3이된다.
                                     // 길이가 3인 arr 배열

 



@ 문자뒤 백슬러쉬0(\0) ; 특수문자

 - 문자의 끝을 나타내기 위한 용도
 
 - NULL 문자라고 일단은 이해한다.

 - 아스키코드표를 참조(블로그 - 메모 에 있음)
 
 - 문자 '숫자 ; 0'의 문자의 아스키코드값은 49 다.
   > 혼돈 주의



널문자를 지녀야 하는 이유?

 - 문자열의 끝을 표현하기 위해서
  > 쓰레기 값과 실제 문자열의 경계를 나타내기 위해

 - printf함수는 널 문자를 통해서 출력의 범위를 결정짓는다.


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

#include <stdio.h>

int main()
{
char str[100] = "hello World !!"; // 길이가 100인 char형 배열 생성
// 이 문자열의 길이(인데스)가 많이 남는다.
// 쓰레기값으로 채워진다. 문자열끝에 항상 '\0' 자동으로 들어간다

printf("%s \n", str);

return 0;
}

// 의미없는 쓰레기 값이 들어가게 된다.
// 하지만 cpu는 어디까지가 실질적인 문자열인지 모른다.
// hello World !! \0(널문자)가 포함된다.

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

printf("hellow \n");
// 이 문자열은 뒤에 안보이지만
// '\0'이 들어가 있다.



문자열과 char형의 배열의 차이점

 - char str1[] = "abc" // 문자열이자 캐릭터형 변수
   // 인덱스는 4다

 - char str2[] = {'a', 'b', 'c'}; // 문자열은 아니다.
   // 인덱스는 3이다.

 - char str[] = {'a', 'b', 'c', \0'}; // 문자열
   // 인덱스는 4이다.


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

#include <stdio.h>

int main(void)
{
int i;

char ch;
char Array[6] = "hello";

printf("-- 변경 전 문자열 -- \n");
printf("%s \n", Array); // 현재 문자열 출력

for(i=0; i<6; i++) // 5번 반복
printf("%c | ", Array[i]); 
// ch문자변수에 Array의 각 요소를 순서적으로 한개씩 출력한다

for(i=0; i<3; i++)
{
ch = Array[4-i];
Array[4-i] = Array[i];
Array[i] = ch;
}
// for문으로 문자열의 요소를 ch에 저장하여
// 각 요소의 문자의 순서를 바꾼다.
// for문이 돌아가는걸 직접 그려서 분석하는것이 이해하기 쉽다.

printf("\n -- 변경 후 문자열 == \n");
printf("%s \n", Array);

return 0;
}

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

 #include <stdio.h>

 int main()
 {
char str[30];

printf("문자열 입력 : ");
scanf("%s", str);
// 어랏 ? 이제는 &가 붙지 않는다.
// 문자열을 사용할때는 &는 쓰지 않는다
// 자세한 사항은 포인터에서 다루겠다.

printf("입력된 문자열 : %s \n", str);

return 0;
 }


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

제 17장 포인터의 이해 - 예제  (0) 2010.07.10
제 16장 포인터의 이해 - 1  (0) 2010.07.10
제 14장 1차원 배열 - 1  (0) 2010.07.10
제 13장 C언어의 핵심 함수 - 3  (0) 2010.07.10
제 12장 C언어의 핵심 함수 - 2  (0) 2010.07.10
Posted by 토실토실천재
2010. 7. 10. 02:03

제 14장 1차원 배열 - 1



※ 문법을 100% 이해하려면, 실습을 거쳐야 완벽한 100% 이해완성
   - 최소한의 연습문제등 문제를 풀어봄으로써 응용력을 키운다.


 배열이란 무엇인가?

  - 두개 이상의 변수를 동시에 선언하는 효과를 지닌다

  - 많은 양의 데이타를 일괄적으로 처리할 수 있다.
   > 예를 들자면 
     for(i=0; i<10; i++)
     Array[i] = 1; // 모든 데이타형을 1로 초기화 한다. 

     // 변수 10개를 일일이 만들필요없이 배열로 선언해서 
     // 편리하게 일괄적으로 처리가 가능한다.

  - 지역적 특성, 전역적 특성 둘다 가짐



 배열 선언에 있어서 필요한 3가지

 - 배열길이 : 배열을 구성하는 변수의 개수(반드시 상수사용)
 
 - 배열 요소 자료형 : 배열을 구성하는 변수의 자료형

 - 배열의 이름 : 배열을 접근할 때 사용되는 이름

 ▼ 정 의 
 int Array[10];
 // int형 데이타형 10개를 저장할수 있는 Array라는 이름의 배열

 - int : 배열 요소 자료형
 - [10] : 배열길이
 - Array : 배열이름
 ==> 4byte(int형) 메모리 10개를 가지는 즉, 40바이트가 할당된다.
 ==> 이 메모리공간의 이름은 Array 라고 한다.

 char A[5];
 // char형 테이타형을 5개 저장할수 있는 A라는 이름의 배열
 // 총 메모리 크기 char형[1byte] X 5개 = 5byte

tip >  마찬가지로 배열도 함수가 호출되었을때 함수내에 정의되어 있으면
         변수와 마찬가지로 메모리공간이 생기고, 함수가 종료되면 메모리가 소멸된다.



 1차원 배열의 접근
  - 인덱스 : 배열요소의 위치를 표현
  - 인덱스는 무조건 0부터 시작한다.
 
총 10개의 데이타를 저장할수 있는 메모리공간
저 하나하나의 데이타를 참조할때는, 하나하나 접근해야한다.


@ index[인덱스] : 기준을 대상으로 얼마나 멀리 떨어져있냐[거리]
 - 기준은 0이다.

 ▼ 접근하는 방법 : 

 - Array[5] : Array배열에 있는 5번째 위치에 해당하는 요소에 접근

 - index 값이 첫번째는 0이다.
   ex) int Array[10] : 마지막요소의 인데스값은 9이다.
   ex) int Array[5] : 마지막요소의 3번째 인데스값은 2이다.

 - Array[3] = 10 // Array배열의 3번째 인덱스에 10을 저장한다.
 
 int main()
{
int Array[10];
Array[0] = 1;
Array[1] = 2;
Array[2] = 3;
......
return 0;
}

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

#include <stdio.h>

int main(void)
{
double sum;
double Array[5]; // double형 데이타타입의 5개의
// 요소를 가진 메모리공간 할당
// 총 8byte X 5개 = 40byte(초기화 안되있음 ; 쓰레기값 포함되있음)

Array[0] = 1.01; // 각 요소마다 double형 값을 저장한다.
Array[1] = 2.34;
Array[2] = 3.34;
Array[3] = 10.3;
Array[4] = 4.5;

// 모든값을 요소마다 더해서 sum값에 대입한다.
sum = Array[0] + Array[1] + Array[2] + Array[3] + Array[4];

printf("Array 전체 요소의 평균값 : %lf \n", sum/5);

return 0;
}

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

 선언과 동시에 초기화

int array[5] = {1, 2, 3, 4, 5};

// int형 데이타 5개 저장할수 있는 array란 이름의 배열 선언을 하고
// 각각의 인덱스에 맞게 순서적으로, 1, 2, 3, 4, 5를 대입한다.

int array1[] = {1, 2, 3, 4, 5}

// int형 데이타를 저장할수 있는 정보를 이런경우는
// 초기화 리스트의 갯수가 있으니까 1, 2, 3, 4, 5의 갯수가 5개 이므로
// 컴파일러가 알아서 숫자를 인식한다 그러믄로 배열요소는 5개

int array2[5] = {1, 2}; // 초기화 리스트 2개가 있다.

// array[0] = 1;
// array[1] = 2;
// array[2] = 0;
// array[3] = 0;
// array[4] = 0;
// 이렇게 자동으로 0으로 초기화 시켜준다.

@ 조심할점 : int array[] ; // 에러발생

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

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