티스토리 툴바

블로그 이미지

카테고리

냠냠이네 폴더 (28)
시스템제어 (26)
잡동사니 (2)
Total398
Today0
Yesterday1

달력

« » 2012.05
    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    

0331 학업일지

시스템제어 / 2010/03/31 15:29
<연결 리스트>


동적자료형은 함수의 실행 중 메모리가 필요에 따라 할당되었다가 사용 후 시스템에게 돌려주는 자료형으로, 메모리 공간 사용의 효율성을 높일 수 있다.
동적자료 구조에는 몇가지가 있지만 그 중 가장 많이 사용되는 것이 연결리스트이다.

옆의 그림을 보자. 
Data라는 태그를 가진 구조체 안에 *next라는 포인터가 지정되어 있다.
그런데 그 포인터는 또 하나의 다른 구조체를 가지고 지니고 있다.
이처럼 연결리스트에서는 변수 자체가 이름을 갖는 것이 아니라, 포인터변수(참조변수)를 이용하여 간접적으로 접근한다.















for문을 넣어서 p의 값이 0이 될때까지의 값을 내어보았다.


























←소스내의 for문이 p에 들어가는 변화를 나타내었다.













<void *>
타입을 가리지 않고 모든 주소를 저장한다.
하지만 메모리에 직접 접근하며 값을 넣을수 없다.

ex>vp는 void * vp = 0;으로 선언되었을때.

ip = vp;
*ip = 100;            ==             *((int *)vp)=100;
왼쪽과 오른쪽이 똑같이 vp안에 100이란 값을 집어넣고 있다.
하지만 왼쪽은 컴파일을 할때 두번일하는 것이고 오른쪽은 캐스팅으로 바로 한번만에 vp안에 100을 넣을수 있다.


<전역변수>









k=10;이라 선언되기전에 printf값이 '0'이 나온걸 볼수있다.
여기서 전역함수의 값이 지정안되어서 메모리 할당영역중 Bss부분에 들어가있는데, Bss영역은 쓰레기값 대신 0으로 채워져 있어 변수가 초기화되지 않아도 0을 출력한다.















전역변수는 분활컴파일시  충돌이  일어날수있다. 그래서 헤더파일에..전역변수를 선언하게 되면  가져가는 main()와 다른 함수로 인해  충돌이 일어날수있다. 이럴경우 헤더파일에 extern int k(외부에 K를선언한다.K가 있다는 존재하에)를 선언하고 종속적인 함수에 다시 int k를 선언하면 사용할수있다. 그리고 분활컴파일시 각각 함수의 변수에 주소가있다 그래서 이함수안 변수끼리 주소가 같을수가 있다. 그래서 분활컴파일시 충돌이 일어날수가 있다. 그래서 LINKing에 기능중에  이 주소가 같아서 충돌을 피하게  하는  기능이 있다 이것을  주소의 재배치라고 한다.지금 우리가 사용하는 일반적인 C같은경우는 이런경우를  관대하게 넘어가지만 C++로 컴파일할경우  바로 링킹error가 나오게된다.

A.cpp 파일
#include"a.h"
int k;
void  test()
{  
  k=20;
}

main.cpp 파일
#include<stdio.h>
#include"a.h"
int main()
{
  printf("%d\n",k);  
  k=10;
  printf("%d\n",k);
  test();
  printf("%d\n",k);
  printf("%p\n",&k);
  return 0;
}

a.h 파일

extern int k;
void test();

gcc -c main.c : main.o 생성
gcc -c A.c : A.o 생성
gcc -o (원하는 파일명) main.o A.o : 파일명.exe 생성



실행이 된다. a.h에서 extern int k와 a.cpp에서 int k 때문에 실행이 가능하다 여기서 test()나 main()두함수중에 하나는 꼭 int k를 선언해야한다.

'시스템제어' 카테고리의 다른 글

0331 학업일지  (0) 2010/03/31
0330 학업일지  (0) 2010/03/31
0329 학업일지  (0) 2010/03/30
0326 학업일지  (0) 2010/03/26
0325 학업일지  (0) 2010/03/25
0324 학업일지  (0) 2010/03/24
Posted by 유성민 꼬막냠냠

0330 학업일지

시스템제어 / 2010/03/31 08:59

<메인함수 이해하기>

아래의 그림을 보자... main()함수에 아무것도 1을 출력시킬만한 무엇인가가 존재 하지않는다.


그런데.... 1이 출력된다... 그 이유는 main()함수 자체가 1이라는 값을 가지기 때문이다.


밑의 그림에서는 DOS창에서 파일이름옆에 1 2 3 4 라는 숫자를 입력후 엔터..

파일 이름(class3_1)을 포함한 문자들의 개수 5가 출력된다.


이번에는 printf()문을 추가하여 Cmd배열 안의 각 인덱스들을 출력하여보자.

Cmd[0]의 주소에서는 파일이름이 출력된다. 이 말은 Cmd[]라는 배열이 파일이름을 포함
하고 있다는 뜻이다.그래서 class3_1, 1, 2가 차례대로 출력된다.

이번에는 조금 난이도를 높여보자... 배열하면 반복문!!! 반복문을 이용하여 배열의 각 인덱

스에 접근하고 출력하였을 경우에도 마찬가지임을 알 수가 있다.



<구조체>

구조체란 의미상으로 연관된 여러 데이터를 하나의 이름으로 묶은 사용자 정의 자료형이다.

- 구조체의 정의와 변수 선언 방법
1) 구조체의 원형(template)을 정의하고, 변수를 선언하는 방법

    -> 여기서는 변수를 main()함수내에서 선언한다.
2) 구조체의 원형과 변수의 선언을 동시에 하는 방법.
3) typedef를 이용하여 구조체를 정의하는 방법


먼저 구조체의 원형을 정의하고 변수를 main()함수 내에서 선언하는 방법을 설명한다.
아래에서는 struct를 이용하여 구조체를 정의하고 변수 선언은 main()함수 안에 있다.
main()함수 안에 B와 C는 int로 정의된 구조체 변수이다.
그 밑에서B와 C를 초기화 하는데 .iNum이 이름뒤에 붙어있는 것을 볼 수 있다.
이처럼 변수의 사용시 (구조체변수).(멤버이름)의 형식으로 사용된다.
※ 멤버란 ? 구조체 정의시 중괄호 안에 있는 각 요소들을 말한다.

B, C에 정수를 초기화하고 출력하였다. 결과는 당연히 문제 없음.

아래의 그림에서는 struct를 이용하여 두가지의 int형 구조체 k를 정의 하였다. 그 후 각각 AA와 BB로 선언하고
BB를 AA에 대입하고 출력하였다.

에러가 뜬다. 이 소스의 실행결과를 통해 각기 다른 태그를 가진 구조체는 다르다는 것을 알 수 있다. 둘 다
int형으로 구조체를 만들었다고 하더라도 서로 대응될 수 없는 관계라는 점을 유의하자.

이번에는 같은 태그(A)의 구조체로 선언된 변수 AAA를 지정하고 그 것을 AA에 대입하고 출력한 그림이다.

여기서는 워닝이 뜨지만 실행파일이 생성됨을 볼 수 있다. 왜? 같은 구조체 태그로 선언된
변수이므로



이제부터는 typedef를 이용하여 구조체를 선언하는 것을 공부하자.
struct로 구조체를 정의했던 것과 거의 비슷함을 알 수있다. 단 반드시 확인할 것!!!
struct에서의 중괄호 뒤에 쓰여진 STUDENT와 typedef에서의 중괄호 뒤의 STUDENT는 
완전 다르다. struct의 STUDENT는 메인함수에서 선언하는 변수와 같은 것으로 메인함수
에서 변수 선언을 하지 않을 때 여기서 대신 변수를 선언할 수 있다.
하지만 typedef에서의 STUDENT는 구조체의 이름(태그) 그 자체이다.

예제소스1) 학생의 이름과 성적을 입력받아 출력하는 프로그램



구조체도 배열의 경우와 같이 변수의 선언시 초기화를 시킬 수 있다. 

예제소스2) 두 점의 위치로부터 거리를 계산하는 프로그램

위의 그림에서
POINTER p1 = {0,0}, p2={1,1}  <<--  이 부분을 유심히 보자.
변수 p1과 p2는 구조체 변수이면서 선언과 동시에 초기값이 주어졌다. 이 때 구조체 필드(멤버)
의 값은 중괄호{} 내에 콤마로 구분된다. 그리고 초기값은 구조체 멤버의 자료형과 반드시 일치
해야 한다.


<구조체를 가리키는 포인터변수>

구조체를 가리키는 포인터변수를 통해서 구조체에 접근할 수도 있다.
포인터변수를 사용하여 구조체에 접근할 때는 앞에서의 dot(.)표기법 대신 ->를 이용한다.

예제소스) 데이터파일에서 몸무게와 키를 읽어 비만을 체크하는 프로그램

'시스템제어' 카테고리의 다른 글

0331 학업일지  (0) 2010/03/31
0330 학업일지  (0) 2010/03/31
0329 학업일지  (0) 2010/03/30
0326 학업일지  (0) 2010/03/26
0325 학업일지  (0) 2010/03/25
0324 학업일지  (0) 2010/03/24
Posted by 유성민 꼬막냠냠

0329 학업일지

시스템제어 / 2010/03/30 09:13
<배열과 포인터>

두번째 for문은 p라는 이름의 포인터에 배열iNum을 대입하였다. p는 포인터(변수)이므로 대입할 수 있다. 그러고 나서 p포인터가 가리키는 값을 출력하면 정상적으로 출력된다.
세번째 for문은 역시 p라는 이름의 포인터에 배열 iNum을 대입하고, 포인터 p를 배열의 형태로 출력하였다.
포인터 p가 가지는 주소값과 배열iNum의 주소값이 같으므로 두번재 for문과 같은 값을 출력하여준다.

아무튼 꼭 기억할 것은???? 
p(포인터)=iNum(배열이름)          실행
iNum(배열이름) =  p(포인터)       에러











<버블 정렬>

원리: 
1) (n-1)번의 비교로 제일 큰 수를 맨 뒤로 보낸다.
2) (n-2)번의 비교로 두번째 큰 수를 뒤에서 두번째로 보낸다.
3) (n-3)번의 비교료 세번째 큰 수를 뒤에서 세번째로 보낸다.
4) 이를 반복하다보면 결국 내림차순이 오름차순으로 바뀐다.




























<다차원 배열>

2차원배열

2차원 배열의 선언과 초기화
2차원 배열의 선언은...

(자료형) (배열이름) [][]로 선언하며..

초기화는 중괄호 내에 각 행별로 다시 중괄호를 넣고 선언하며, 각 행마다 콤마(,)를 붙인다.
(아래 그림 참조)


※2차원배열을 초기화하여, 화면에 출력하는 프로그램

위의 그림에서는 선언된 2차원 배열을 for()문을 이용하여 각 행별, 열별로 정렬된 값을
출력하여 준다.

※array+1과 *array+1을 했을 경우

위의 그림에선 그 위의 그림에서 배열이름에 1을 더해준 것이다. 배열이름에 1씩 더했을때
주소값이 16씩(위의 그림에서 16진수로 출력하였으므로) 증가 하는 것을 볼 수 있다.
이는 'array+1'을 했을 경우 배열 한칸 한칸의 이동이 아닌 한 행의 이동임을 보여주고 있다.
 그림에서는 포인터 array에 1을 더해주고 있다. 이 경우에는 4바이트의 주소값이
증가하였다. 이 그림을 통해 *array+1은 각 칸별로 이동한다는 것을 알 수있다.

※&array +1을 하면

위의 그림은 array라는 배열이름의 주소값에 1을 더해준다. 위의 결과에는 나와있지 않지만
배열이름(array[0][0])의 주소는 12FF48이다. 두 주소값의 차이는 48(10진수)이 차이가 난다
이를 통해 알 수 있는 것은 &array에 1을 더하면 배열의 범위 그 다음의 공간으로 넘어감을 알 수있다.


<형식인수로 다차원 배열이 사용되는 경우>
다차원 배열이 형식인수로 사용되는 경우에는 첫 번재 색인을 생략할 수있다. 그러나 두 번재 색인부터는
반드시 명시해 주어야 한다.

그림에서 빨간색 네모로 둘러쌓인 부분을 보자...(이 것은 임의로 내가 설정 한 것이다.)
위의 네모에서는 배열이름 자체의 크기를 sizeof연산자를 통해 출력한다. 배열 전체의 크기이므로 36바이트가 출력된다.         그런데 밑의 그림에서는 4가 출력되었다. 왜??? 배열이 함수의 인자로 넘어오면서 포인터화 되었기 때문이다. 포인터의 크기는?? 당연히 4바이트!!!

그리고 마지막에 출력된 Answer에 42가 출력된 것은.... 덧셈 할 줄 알면 이해 함.







※sizeof()연산자를 이용하여 배열의 개수 구하기


<문자열>

 Null의 값을 제외한 순수 문자의 개수 구하기 



원래는 "하이~!"의 글자 수를 출력하면 6이 나온다. 그런데 그림에서는 5이다.
그 이유는 sys_strlen()함수에 포인터를 지정해주고, for()문을 돌릴 때 포인터가 가리키는 값이 0이 아닐때 까지 반복문을 수행하게 코딩 해놓았기 때문이다.  여기서 포인터가 0이 아니다라는 것은
NULL값이 아니다는 것이다. 








'시스템제어' 카테고리의 다른 글

0331 학업일지  (0) 2010/03/31
0330 학업일지  (0) 2010/03/31
0329 학업일지  (0) 2010/03/30
0326 학업일지  (0) 2010/03/26
0325 학업일지  (0) 2010/03/25
0324 학업일지  (0) 2010/03/24
Posted by 유성민 꼬막냠냠