달력

52024  이전 다음

  • 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

putchar 함수의 활용 : 문자열의 주소접근과 포인터

 

 

putchar함수는 하나의 문자를 출력하는 함수이다.

용법은

putchar('출력문자 변수명');

와 같이 쓴다.

 

 

자 아닥하고 문제!

아래 반복문을 이용하여 testprogram을 출력하라.

 

 

즉, 아래처럼 하라.

단, 변수는 추가로 쓰지 말고, 출력함수도 putchar만 쓰라.

오로지 조건식과 실행식만 추가해라.

힌트 : 문자열의 각 글자와 그 주소값을 이용하라.

5분 주께..

1분..

2분..

 

정답은 아래와 같다.

 

이상으로 'putchar 함수의 활용'에 대하여 알아보았다.

아래 손가락! 눌러주시고 좋은 하루 보내세요~*

 

Posted by C언어 보이
|

헥사뷰:hexaview,포인터, 함수포인터와 void 포인터

 

오늘은 void 포인터와 함수 포인터에 대하여 배웠습니다.

함수 포인터는 함수를 가리키는 포인터 입니다.

즉, '함수의 반환형+(포인터표시*+포인터명)+(인자)' 와 같이 쓰면 됩니다.

그런 후 사용법은 함수와 같이 하면 됩니다. 즉, '함수 포인터이름(인자)'와 같이 하면 됩니다.

Void 포인터는 형이 없는 포인터로서 'void*포인터이름'으로 선언합니다. 즉, 모든 자료형을 대입할 수 있으며, 대입 및 출력에는 원하는 자료형으로 지정을 하면 됩니다 (이를 캐스팅 이라 합니다).

 

아래의 헥사뷰를 예로 설명하겠습니다.

 

헥사뷰 함수를 선언하고, 메인에서 호출합니다.

메인에서 헥사뷰 함수 호출시에 인자로 inum의 주소를 전달했습니다.

 

 

아래 헥사뷰 함수를 보면..

Vpdata의 값(즉, inum의 주소)을 출력합니다.

 

 

아래 반복문에서는 1바이트 char형으로 출력을 하고 있습니다. 즉, 4바이트 숫자를 1바이트 씩 쪼개서 보고 싶기 때문에 이와 같이 쓰는 것입니다.

출력문에서 1바이트 자리만큼 출력을 한 후에 +1을 해주어, 다음 반복문에서 다음 바이트의 값을 나타내도록 하고 있습니다.

이렇게 메인의 inum 변수 메모리 공간의 값을 모두 출력하였습니다..그 후 옆 칸에 아스키 코드 출력을 위하여 아래의 코드를 작성합니다.

 

보면은 값이 32~127 사이 즉 아스키표에서 문자에 할당된 값일 때에만 해당 문자를 출력합니다.

 

함수포인터와 void 포인터 그리고 헥사뷰에서의 활용에 대하여 알아보았습니다.

추천 눌러주세요 ㅋㅋ

 

Posted by C언어 보이
|

배열과 포인터의 다양한 형태와 활용에 대하여 공부하였습니다.

-----------[순서]--------------

[1] 배열

1. 삼차원 배열의 개념

2. 다차원 (이차원) 배열의 활용문제

   

[2] 포인터

1. 다차원 포인터의 개념과 활용

(1) 개념

(2) 활용

2. 다차원 배열과 포인터의 관계

(1) 개념

(2) 포인터 배열 'int * pnum[2]'와 배열 포인터'int(*parr)[2]'

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

   

   

[1] 배열

1. 삼차원 배열의 개념

예시로 설명하겠습니다.

-      1차원 배열의 예: 학생의 국, 영, 수 성적을 1차원 배열로 저장하라.

   

   

   

각 각의 번지는 국, 영, 수 순서입니다.

   

-      2차원 배열 : 출석번호 1, 2, 3번 학생들의 국, 영, 수 성적을 2차원 배열로 저장하라.

위 1차원 배열의 구조가 그대로 들어가 있습니다. 다만, 1차원 배열이 원소가 된다는 점만 다릅니다. 참고로 5행, 6행, 7행의 실행결과는 동일합니다. 편한데로 쓰면 되겠습니다.

   

   

 -      3차원 배열: a반과 b반의 출석번호 1, 2, 3번 학생의 국, 영, 수 성적을 입력하라

   

   

'1차원->2차원 배열'과 '2->3차원 배열'은 동일한 관계를 가집니다. 즉, 3차원 배열은 2차원 배열을 원소로 가진다. 소대->중대->연대의 개념이라고 하면 될까요?

이렇듯 배열, 특히 다차원 배열은 자료입력을 하는 데에 용이합니다. 특히, 각종 명부, 신체 사이즈 등 정보의 종류와 구조가 특정되어 있는 경우에 유용합니다.

   

   

2. 다차원 (이차원) 배열의 활용문제

아래는, 이차원 배열의 활용에 관해 3문제 중 한 문제입니다.

학생들의 시험성적을 관리하는 프로그램입니다. 입력된 시험성적을 총점 구하기, 평균 구하기 등에 사용할 수 있습니다.

(상세한 설명은 제 블로그 'http://inocenttome.tistory.com/entry/20140331-03-이차원-배열의-활용-문제-3-성적관리-프로그램' 에 있습니다)

   

   

   

특징.

1.     입력과 출력을 같은 반복문을 쓰지 않고 나누어 코딩하였습니다. 수정과 디버깅의 용이함 때문으로 보이지만 사실 실력이 모잘랐..;

2.     그리고 숫자 외의 정보표현을 위해 name이라는 문자열 배열을 만든 것입니다. 각 각의 반복문에 분기문을 지저분하게 첨가할 수도 있었으나, 가능한 문자정보의 출력을 자동화하고자 노력하였습니다.

   

가벼운 마음으로 코드를 함 슥 보면… Score[i-5] 이 부분은 원래 score[i] 였습니다. 원래 의도한 바가 있어서 [i-5]형태로 쓴 건데, 코딩하다가 그 용도가 없어졌습니다. 이렇듯, 처음 변수를 정의할 때에도 전체 코드에서의 쓰임을 고려하여야 하며, 이를 간과하고 변수를 정의하면 후에 변수의 사용형태가 아래처럼 복잡해 집니다 (타산지석).

   

   

   

아래는 출력용 반복문입니다. 메인은 두 반복문 중에 아래 쪽 반복문입니다.

이중 반복문인데, 살펴보면 안쪽 반복문을 수행하기 전에 (즉, 철수의 각 과목 성적을 출력하기 전에), 사람의 이름이 찍혀야 합니다.

   

   

   

[2] 포인터

1. 다차원 포인터의 개념과 활용

(1) 개념 : 포인터의 포인터를 더블포인터라고 하며, 더블포인터를 가리키는 삼중포인터, 이 삼중포인터를 가리키는 사중포인터 등을 모두 합해 다차원 포인터 라고 합니다. '*'을 100개 까지 붙히면 백중 포인터도 만들 수 있으나 다차원 포인터는 잘 쓰이지 않으며 그나마 쓰이는 것이 더블 포인터 입니다.

(2) 더블 포인터의 활용 :

함수 내의 static 변수 접근을 위해 주로 사용됩니다. 아래 코드식으로 적어보면.. 

---------------[코드시작]----

main

{

int num=100;

int * pnum=&a;

int **ppnum=&pnum;

func(ppnum);

 }

   

void func(int** ppnum)

{

static snum=10;

*ppnum=&snum;  //ppnum이 &pnum이므로, *ppnum은 pnum이다.

                       //즉, 더블포인터로 메인의 싱글 포인터를 접근할 수 있게 된다.

                       //이 pnum에 &snum을 넣게 된다.

}

   

---------------[코드 끝]----

   

   

2. 다차원 배열과 포인터의 관계 

: 예제와 개념이 교재에서 충실히 설명되므로, 제가 이해한 표현으로 적겠습니다. 참고 바랍니다.

(1) 개념

2차원 배열의 이름이 곧 더블 포인터는 아닙니다.

   

크게 두 가지 이유가 있습니다.

1) 첫 번째로 배열명은 포인터와 달리 그 값이 여러 가지를 의미합니다.

포인터는 쉽게 말해 '아래 혹은 위로 타고 들어가는 것'이나 배열명은..

가령, 이차원 배열 'inum[2][2]'의 배열이름 inum은,

'배열 전체의 시작주소'이기도 하며,

'0번째 행의 시작주소inum[0]'이기도 하며,

'0번째 행의 0번째 원소 주소inum[0][0]'이기도 하기 때문입니다.   

   

 2) 두 번째로, 연산 (증가, 감소)의 형태가 다릅니다.

배열명 inum에 +n을 하면 '배열의 전체길이*배열자료형의 크기*n'만큼 주소 값이 건너뜁니다.

하지만 배열명 inum을 가리키는 'int형 싱글 포인터 pinum'(int*pinum=inum)에 +n을 하면 이는 '자료형의 크기*n'만큼 주소 값이 증가할 뿐입니다. 그렇다고 'int형 더블 포인터 ppnum'에 +n을 하여도 마찬가지 크기만큼 증가합니다. 즉, 포인터의 연산은 '자신의 선언형태'에 따라가는 것이지, 가리키는 대상(배열명)에 따라 달라지는 것이 아닙니다. 그럼 포인터의 연산을 배열명과 동일하게 하려면 어떻게 해야 할까요?

따라서 이차원 배열을 가리키는 포인터로 '포인터 배열'이라는 것이 필요해집니다. 아래를 참고.

   

   

(2) 포인터 배열 'int * pnum[2]'와 배열 포인터'int(*parr)[2]'

1) 포인터 배열: 이미 알고 있듯이 배열을 선언할 때에 배열의 자료형을 명시해 주어야 합니다. 가령 '정수형의 배열'은 int num[2] 처럼 말입니다. 즉, '자료형int+배열명+인자의 개수[2]'.

그럼 '정수형 포인터의 배열'의 선언방식은? 똑 같습니다. 즉,  '자료형int*+배열명pnum+인자의 개수[2]' 입니다.

   

2) 배열 포인터: 이미 알고 있듯이 포인터를 선언할 때에 포인터의 자료형을 명시해 주어야 합니다. 가령 '정수형의 포인터'는 int* pnum 처럼 말입니다. 즉, '자료형int+포인터표시*+포인터명pnum'.

그럼 '정수형 배열 포인터'의 선언방식은? 똑 같나요? 예 거의.

즉, '자료형+포인터표시+포인터명'의 위 방식 마지막에...배열 인자의 개수만 더해주면 됩니다. 즉, '자료형int+(포인터표시*+포인터명pnum)+배열인자의 개수[2]' 입니다.

 

잘 보셨으면 손가락을 꾸욱 눌러주세요~~

링크도 많이 많이 해 주세요 ㅎㅎ

   

Posted by C언어 보이
|

Symbol table은 자료형, 변수명, 주소를 나타내는 테이블

포인터는 주소다. 즉, 특정 메모리 영역 (변수)의 위치를 나타내는 숫자이다.

%08x: 빈자리는 0을 체우고, 8자리를 표현. X는 주소를 16진수로 표현하라는 말. %p와 동일

(int *)0x12FF70 = 100. 케스팅 연산자 * : 괄호안 숫자가 Int형 자료형의 메모리 주소 이며, 4바이트를 쓸 것임을 알려 줌.

 

 

피보나치 수열 프로그래밍

    for(count=3;count<=n;count++)

    {

        printf("Term Number : %d    C¬¢¬ø¨£¢® ùo¯¡© : %d\n",count,three);

        one=two;

        two=three;

        three=one+two;

    }

숫자를 0개, 1개, 2 개 입력한 경우 (count가 0,1, 2인 경우), 각각 분기문으로 받아서 return 0.

 

포인터(*)는 두 가지 의미임. 주소(캐스팅) 및 값..

 

 

Posted by C언어 보이
|

[C언어 핵심강의 05] 포인터의 이해

 

변수란 무엇인가? 기록할 수 있는 공간 (블록)이다.

하드웨어 디스크 상의 어떤 위치의 블록 (실제로는 아주 아주 작은 조각)의 상태 (:기록된 형태. 즉 값)가 '0000 0111'라고 되어 있다 하자. 이는 2진수로서 10진수로 바꾸면 7이다.

 

만약 이 블록의 이름을 num 이라고 하면, 이제부터 이 블록은 num이라는 변수이며, 이 블록에 적힌 상태 7이 num의 값이다. 그리고 하드웨어 상에서 이 블록의 위치가 곧 num의 주소이다.

즉, '변수의 주소'는 하드웨서 상에서 블록(변수)의 위치를 표시해 놓은 숫자이다. 집 주소를 예로 들면, 우리집 우체통이 변수이고 우체통의 주소가 변수의 주소 그리고 우체통의 내용 (편지, 소포 등)이 변수의 내용이다.


그리고 컴퓨터가 2진수를 다루는 만큼 (즉, 값의 저장도 2진수 상태. 연산도 2진수를 기반으로 이루어짐), 메모리를 8비트나 16비트 단위로 표기한다. 그래서 메모리 주소를 흔히 16진수로 표현한다.

 

자 그럼..num의 값이 7이고 그 주소가 0x12ff76이라고 하자.

근데 이 num의 주소도 숫자이므로, 이 주소값을 다른 변수의 값으로 저장할 수도 있지 않을까?

있다. 그렇게 하겠다고 선언하는 지시자가 포인터 연산자 (*)이다.

 

따라서 포인터 변수는 다른 '변수의 주소값'을 값으로 저장하는 변수이다. 

 

아래 그림을 보면서 이해하자.

아래 pnum에 저장된 값은 num의 조소값이다. 즉, pnum==&num 이다.

그러면 'pnum의 값(주소)안에 있는 값(num의 값 7)'을 가리키고 싶을 때는 어케해야 할까?

이 땐 *을 붙혀, *pnum이라 한다.

 

 그럼 또 이렇게도 생각해 볼 수 있겠지...

pnum의 주소를 값으로 갖는 변수 ppnum (이를 더블포인터 라고 한다)을 말이야.

그럼 ppnum은 뭐지? &pnum이지

그럼 *ppnum은? pnum 즉, &num 이지.

글머 **ppnum은? *pnum즉, *(&pnum) 하여 7이지.

으크크크크~~  헷갈린다 그치?

그니깐 '포인터 연산자 표현'은 이해만 했다고 넘어가지 말고, *이랑 주소표시&를 앞뒤로 붙혀가며 그 형태에 익숙해 져야 한다구.

 

 

 위에서 설명한 내용을 한 화면에 합쳐 보았어.

 

 이상으로 포인터의 이해 : 변수의 개념, 변수의 주소, 더블포인터에 대해 공부해 보았습니다.

질문을 댓글로, 강의료는 손가락 꾸욱~*


Posted by C언어 보이
|