20140325 (배열, 문자열)

27일차

 

 

--------------

Array ( 배열 )

--------------

어제에 이어 계속 배열을 배웠다.

바로 예제 소스를 보자.

ex) 예제 소스

#include <stdio.h>

int main()
{
  int  arr1[5= {1,2,3,4,5};
  int  arr2[] = {1,2,3,4,5,6,7};
  int  arr3[15= {1,2};
  int  ar1Len;
  int  ar2Len;
  int  ar3Len;
  int  iCnt;

  printf("배열 arr1의 크기 : %d \n"sizeof(arr1) );
  printf("배열 arr2의 크기 : %d \n"sizeof(arr2) );
  printf("배열 arr3의 크기 : %d \n"sizeof(arr3) );

  ar1Len = sizeof(arr1) / sizeof(int);
  ar2Len = sizeof(arr2) / sizeof(int);
  ar3Len = sizeof(arr3) / sizeof(int);

  for(iCnt = 0; ar1Len > iCnt; ++iCnt)
  {
    printf("%d ", arr1[iCnt]);
  }
  printf("\n");

  for(iCnt = 0; ar2Len > iCnt; ++iCnt)
  {
    printf("%d ", arr2[iCnt]);
  }
  printf("\n");

  for(iCnt = 0; ar3Len > iCnt; ++iCnt)
  {
    printf("%d ", arr3[iCnt]);
  }
  printf("\n");

  return 0;
}

출력 화면 

위에서 보았듯이

int arr1[5] = {1,2,3,4,5}; 선언시 {} 를 사용해서 초기화가 가능하고

int arr2[] = {1,2,3,4,5,6,7}; 변수 뒤에 []만 붙이면 몇 개나 들어가는지 자동으로 샌다.

int arr3[15] = {1,2}; 첫번째와 두번째만 넣고 나머지는 0으로 초기화.

 

- 배열은 잘 사용해야 하는게 다른 메모리를 침범이 가능하므로

잘 확인하고 사용해야 한다.

 

- cp == cStr ?????

#include <stdio.h>

int main()
{
  char *  cStr = "Good morning!";
  char *  cp1;
  char *  cp2;

  cp1 = cStr;

  printf("%c \n", *cp1);

  printf("%s \n", cp1);
  printf("%s \n", cStr);

//  ++cp1;
  cp1 = cp1 + 5;

  printf("%s \n", cp1);
  printf("%s \n", cStr+5);

  cp2 = cStr;

  printf("%c \n", cStr[0]);
  printf("%c \n", cp2[0]);
  printf("%c \n", *(cp2+0) );
  printf("%c \n", *(cStr+0) );

  return 0;
}

출력 화면

 

이것을 통하여

cp == cStr

똑같이 주소값을 저장하고 있다.

조금 다른데

cp의 경우 주소값이 가리키는 값을 수정할 수 있는 반면

cStr의 경우 수정이 불가능하다.

const char * const cp == cStr 이게 정확한 똑같은 Data type이다.

 

 

 - 문자열, 문자배열

무조건 문자가 모여있다고 문자열이라고 안한다.

마지막에 NULL이 없으면 printf함수 사용 시 NULL 만나기 전까지

출력하므로 계속 출력을 하게되므로 의도치 않은 상황이 발생할 수 있으니

위험하다.

 

 

- 주소상수

#include <stdio.h>

int main()
{
  char  str[] = "Hello world!\n";
  char *  cp = "Hello world!\n";

  printf("str : 0x%08X \n", str);
  printf("&cp : 0x%08X \n"&cp);
  printf("cp : 0x%08X \n", cp);
  printf("main : 0x%08X \n", main);

  str[5= '!';
  cp[5= '@';

  printf(str);
  printf(cp);
  printf("Hello world!\n");

  return 0;
}

출력 화면

 

 

- 그리고 위에서 보면

cp[5] = '!'; 를 자세히 보면 cp포인터 변수가 가리키는 곳은 CODE 영역의 상수값이다.

윈도우에서는 실행이 되지만 리눅스에서는

이렇게 오류가 난다.

Windows 에서는 RO영역의 수정을 어느정도 허용하지만 (위험함)

linux 에서는 RO영역의 수정을 금지한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

설정

트랙백

댓글

20140324 (전역변수, 메모리 구조, 재귀함수)

26일차

 

--------------------

전  역  변  수

--------------------

- 지역변수와 다르게 어디서든 읽기 쓰기가 가능한 변수.

- 어떤 함수에서 쓰기 가능하기 위해 컴파일러가 제일 먼저 읽어야 하니

맨(include 밑에) 위에 선언한다.

- 기본적으로 0으로 초기화 돼있음.

- 변수가 만들어 지는 때

    지역변수 : Run Time

    전역변수 : Compile Time

 

- 지역변수는 Load 하면서 Mem에 할당됨.

- 전역변수는 컴파일당시에 생성되기 때문에 실행파일에 할당되어 있음.

 

ex) 예제 소스

#include <stdio.h>

void Add(int iVal);
int iNum;
int iNum1 = 10;
int iNum2;
int iNum3 = 20;
int iNum4;
int iNum5 = 30;
int iNum6;
int iNum7 = 40;

int main()
{
  printf("iNum : 0x%08X \n"&iNum);
  printf("iNum1 : 0x%08X \n"&iNum1);
  printf("iNum2 : 0x%08X \n"&iNum2);
  printf("iNum3 : 0x%08X \n"&iNum3);
  printf("iNum4 : 0x%08X \n"&iNum4);
  printf("iNum5 : 0x%08X \n"&iNum5);
  printf("iNum6 : 0x%08X \n"&iNum6);
  printf("iNum7 : 0x%08X \n"&iNum7);
  printf("Add : 0x%08X \n", Add);
  printf("main : 0x%08X \n", main);
  printf("printf : 0x%08X \n", printf);

  printf("iNum : %d \n", iNum);
  Add(3);
  printf("iNum : %d \n", iNum);
  ++iNum;
  printf("iNum : %d \n", iNum);

  printf("문자열 주소 : 0x%08X \n""Welcome");
  return 0;
}

void Add(int iVal)
{
  if(0 == iNum)
  {
    printf("iVal : 0x%08X \n"&iVal);
  }
  
  iNum = iNum + iVal;
}

출력 화면

위에서 보았듯이 전역변수로 선언되 있는 변수는

main에서도 Add에서도 접근이 가능하다.

자세히 볼게 전역변수들을 관찰해 보면

초기화된 변수와 초기화 안된 변수의 주소값이 몰려 있는게

다르다.

초기화된 변수는 함수들의 주소값에 더 가깝다.

또 상수의 주소도도 초기화된 변수들의 주소와 가깝다.

 

 

 

 

 

-----------------

재  귀  함  수

-----------------

- 자신을 다시 부르는 함수

- 사용을 비추천

 

ex) 예제 소스

#include <stdio.h>

void Recursive(int iNum);

int main()
{
  Recursive(3);

  return 0;
}

void Recursive(int iNum)
{
  if(0 >= iNum)
  {
    return;
  }
  printf("Recursive call!! %d \n", iNum);

  Recursive(iNum - 1);
}

 출력 화면

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

설정

트랙백

댓글

20140321 (함수, 지역변수)

25일차

 

--------------------

Function ( 함  수 )

--------------------

- 어제 보았듯이 어떤 기능을 하는 역할.

- int Add(); 이런 형태는 함수의 원형( prototype, interface ) 라고 한다.

- int Add() { A } 이런 형태는 함수의 정의이다.

뭐 설명은 어려운데 예제를 보면 쉽다.

예제를 보자.

#include <stdio.h>

int Add(int iNum1, int iNum2);  // 함수 선언, 원형

/*
int Add(int iNum1, int iNum2)    // 이렇게 main 위에 와도 괜찮다.
{        // 선언, 정의? 다 같이 한다?
  int iResult = iNum1 + iNum2;

  return iResult;
}
*/


int main()
{
  int  iNum;

  iNum = Add(1020);
  printf("%d \n", iNum);

  return 0;
}

int Add(int iNum1, int iNum2)    // 함수 정의
{
  int iResult = iNum1 + iNum2;

  return iResult;
}

프로그램 진행 순서가

이렇게 흘러간다.

10, 20 이란 인수를 받아서 Add 함수에서 그 값만 받는다.

받은 값을 iResult에 넣어서 반환한다.

 


 

위에서 본 바와 같이

어떤 일정한 반복된 코드나,

역할을 나눌때

함수를 만들어 사용한다.

 

 

 

여기서 잠깐,

printf, scanf 등등 가져다 쓰는 함수들을 모아서

라이브러리 라고 부르고 컴파일 과정 중 링크때 연결된다.

 

우리가 만든 함수는 전처리 과정 중에 불러온다.

 

 

 

 

 

 

-------------

지역변수

-------------

- { 에서 } 까지가 지역변수의 수명.

ex) 예제 소스

#include <stdio.h>

main()
{
  int iNum;    // main 의 지역변수 iNum

  iNum = 0;

  if(0 == iNum)
  {
    int iNum = 1;    // if 의 지역변수 iNum
  }                      // if 의 지역변수 iNum 소멸

  printf("iNum : %d \n", iNum);    // main 의 지역변수 iNum

  while(2 > iNum)    // main 의 지역변수  iNum
  {
    int iTemp = 0;    // while 의 지역변수 iTemp 생성
                          // while문이 반복할 때마다 iTemp 생성, 소멸 반복
    ++iTemp;
    ++iNum;
    
    printf("iTemp : %d \n", iTemp);
    printf("iNum : %d \n", iNum);
  }                      // while문 지역이 끝나면서 iTemp도 소멸

  {
    int iNum = 0;    // 이름없는 지역의 지역변수 iNum

    
    iNum = 1000;
  }                     // 지역이 끝나면서 iNum도 소멸

  printf("iNum : %d \n", iNum);    // main 의 지역변수 iNum

  return 0;
}

출력 화면

위에서 보았듯이 지역변수끼리 이름만 같았지

서로 다른 주소를 사용하기 때문에 서로 영향을 끼칠 수 없다.

변수 이름이 같을 경우

더 작은 지역의 변수의 이름을 사용하고

없을 경우 한층 위 지역의 변수를 사용한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

설정

트랙백

댓글