메모리에 따른 구조체 변수와 포인터 사용법


main.c

굉장히 중요한 기술이므로 꼭 숙지 해놓자!!


구조체 배열의 선언 및 접근의 방법이 일반적인 배열의 선언 및 접근의 방벙과 다르지 않듯이, 구조체 포인터 변수의 선언 및 연산의 방법도 일반적인 포인터 변수의 선언 및 연산의 방법과 다르지 않다.


main1.c



포인터 변수를 구조체의 멤버로 선언하기


main2.c


main3.c


구조체 변수의 주소 값과 첫 번째 멤버의 주소 값 

구조체 변수의 주소 값은 구조체 변수의 첫 번째 멤버의 주소 값과 동일.


main4.c



구조체의 정의와 typedef 선언

typedef int INT;    ->    int의 또 다른 이름 INT를 부여!

컴파일러에게 전달하게 됨.

typedef struct smart Smart; -> struct smart구조체의 또 다른 이름 Smart를 부여!


main5.c


main6.c


main7.c


함수로의 구조체 변수 전달과 반환

구조체를 인자로도 쓸 수 있고 반환값으로도 넘길 수 있다.

될 수 있으면 쓰지마라.

(통으로 쓰기 때문에 통째로 복사된다. 같은 용량이 동시에 존재해서 메모리가 두배로 든다.)

한다면 주소값으로 넘겨라.


함수의 인자로 전달되고 return문에 의해 반환되는 구조체 변수



main8.c


main10.c


    



20140409 - 구조체 메모리 할당

c언어 2014. 4. 9. 17:26 Posted by Owen.K

컴파일러마다 되는 전처리도 있다.

#pragma pack(1) -> 메모리할당공간을 1byte씩 최적화 시킨다.

#pragma pack(4) -> 메모리할당공간을 4byte씩 최적화 시킨다.

     32bit운영체제의 컴파일러와 동일.


32bit 운영체제 컴파일러 


main1.c


#pragma pack(1) 썼을 때 메모리 할당


main2.c


변수 메모리에 맞게 배치하였을 때


main.c



구조체 : 하나 이상의 변수(포인터 변수 배열 포함)를 묶어서 새로운 자료형을 정의하는 도구.


struct smart        ->smart라는 구조체 선언 및 정의

{

char name[7];

char phone[14];

int age;

};                    ->smart라는 이름이 int나 double과 같은 자료형의 이름이 되는 것.

기본 자료형 변수를 묶어서 새로운 자료형을 만든 것이다. '사용자 정의 자료형'이라고 한다.


구조체 변수의 선언과 접근


 


main1.c


main2.c


ch22-1.c


구조체 변수의 초기화

변수들을 선언과 동시에 초기화 할 수 있듯이 구조체 변수도 선언과 동시에 초기화 할 수 있다.

초기화 방법은 배열의 초기화와 동일하다.


main3.c


구조체 배열의 선언과 접근

변수를 선언할 때 배열의 선언을 고려하듯 다수의 구조체 변수를 선언할 때에는 구조체 배열의 선언을 고려해야 한다. 일반적인 배열의 선언방법과 동일하다.



main4.c


main.c


구조체 배열의 초기화



main5.c


ch22-2.c




20140407 - 입출력이외 문자열 함수

c언어 2014. 4. 7. 17:36 Posted by Owen.K

입출력 이외의 문자열 함수    C-><string.h>

JAVA->String class

C++  ->String class

기존의 함수를 이용하는 이유

1. 개발 속도가 올라간다.

2. 안정성.


문자열의 길이를 반환하는 함수 : strlen

typedef unsigned int smart  (unsigned int(기존의 type) smart(new type))

smart타입의 변수를 만듬

 

main.c

 

main1.c

 

 


문자열을 복사하는 함수들 : strcpy, strncpy

char * strcpy(char *dest, const char *src);


char * strncpy(char *dest, const char *src, size_t n);

 

main2.c

 


 

문자열을 덧붙이는 함수들 : strcat, strncat

char * strcat(char * dest, const char * src);

dest의 뒤에 src를 복사

char * strncat(char * dest, const char * src, size_t n);

src의 문자열 중 size_t n만큼 dest뒤에 덧붙여라

 

main3.c

 

 

 


문자열을 비교하는 함수들 : strcmp, strncmp

int strcmp(const char * s1, const char * s2);

int strncmp(const char * s1, const char * s2, size_t n);

->두 문자열의 내용이 같으면 0, 같지 않으면 0이 아닌 값 반환

 

main4.c

 


그 이외의 변환 함수들    

int atoi(const char * str);            //문자열의 내용을 int형으로 반환

long atol(const char * str);         //문자열의 내용을 long형으로 반환

double atof(const char * str);     //문자열의 내용을 double형으로 반환

 

main5.c

 






문자열 단위 입출력 함수

puts - 문자열 그대로 출력해낸다. 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄진다.


fputs - 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄지지 않는다.


gets - 문자열을 입력한다. 할당된 배열의 길이를 넘어서면 오류가 발생. 보안에 매우 취약하다.


fgets - stdin으로부터 문자열을 입력 받아서 배열 str에 저장하되, sizeof(str)의 길이만큼 저장함.

    문자열을 입력 받으면 문자열의 끝에 자동으로 널 문자가 추가된다.







표준 입출력과 버퍼


표준 입출력 기반의 버퍼

운영체제가 제공하는 '메모리 버퍼'를 중간에 통과하게 된다. 

메모리 버퍼는 데이터를 임시로 모아두는 메모리 공간.

입력버퍼의 비워짐은 데이터의 소멸을 의미한다.


fflush함수 - 출력버퍼에 저장된 데이터가 버퍼를 떠나서 목적지로 이동. 강제 입출력








20140403 - 문자 출력 함수

c언어 2014. 4. 3. 17:27 Posted by Owen.K

문자 출력 함수


putchar - 문자하나를 놓는다. 인자로 전달된 문자를 stdout으로 표현되는 

  표준 출력 스트림으로 전송하는 함수.

  이 함수를 호출 시 int putchar(int c->정수를 넣어라)

  그 결과가 int로 바뀐다. 모니터에만 출력


fputc - 문자를 전송할 스트림을 지정할 수 있다.

     int fputc(int c, FILE *stream);

     출력하는 방향도 바꿀 수 있다. 원하는 대로 출력할 수 있다.


getchar -  stdin으로 표현되는 표준 입력 스트림으로부터 하나의 문자를 입력받아서 반환하는 함수.

   문자하나를 가져옴. 아스키코드로 반환됨. 한글자를 읽어올 때   


fgetc - 하나의 문자를 입력 받는 함수. 입력 받을 스트림을 지정할 수 있다.



main1.c


main3.c


main4.c


main2.c


main5.c




main 함수로의 인자 전달

메인 함수도 인자를 받을 수 있다. OS에서 메인의 인자를 넘겨줌.OS에서 gcc -o main main.c는 

인자 4개로 받아들임인자에 따라서 실행 방법을 바꿀 수 있다적었던 인자들의 개수, 글자들을

출력해낼 수도 있다.

 

cl main.c (enter)-> main hi hello(enter)->인자 3개로 받아들임.



main.c




도전!프로그래밍3(수정중....)

 

스트림 - 프로그램상에 모니터와 키보드를 대상으로 데이터를 입출력 하기 위해서는 

이들을 연결시켜주는 다리가 필요하다. 이러한 다리의 역할을 하는 매개체를 

스트림이라 한다.

 

redirection - 방향을 바꾼다.

cmd창에서 dir > a.txt하면 디렉토리에 나오는 내용이 a.txt이 생성되며 저장됨.

 

stdin 입력 0(c에서는 이렇게 쓴다.)키보드

stdout 출력 1(c에서는 이렇게 쓴다.) 모니터

stderr 에러 2(c에서는 이렇게 쓴다.)모니터

 

dir 2> a.txt - errortxt로 보내라. error만 리-다이렉션 시킨다.

dir 1> a.txt

error 메시지 따로 표준 메세지 따로 출력해냄.

 

dir >> a.txt - 기존의 내용을 지우지 않고 a.txt에 저장.

 

tree - 하위 디렉토리를 보여줌.





 

다차원 배열

3차원 배열 흔히 사용되는 배열이 아니고 복잡하지 않은 구조이다.

                          여러 개의 2차원 배열이 모여있는 형태로 이해하는 것이 합리적이다.



 (예시1)





포인터의 포인터

포인터 변수를 가리키는 또 다른 포인터 변수.

포인터 변수는 무조건 종류에 상관없이 주소 값을 저장하는 변수. 차이는 변수가 가리키는 대상.

 




다중포인터

삼중 포인터 변수는 이중 포인터 변수를 가리키는 용도, 이중 포인터 변수의 주소 값을 저장하는 용도로 사용. 함수 내부에서 함수 외부에 선언된 변수에 접근하는 방법 제시

 

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

2차원 배열의 이름이 더블 포인터 형이라는 오해를 절대로 해서는 안된다.

 

2차원 배열이름의 포인터 형





20140401 - 함수포인터

c언어 2014. 4. 1. 17:37 Posted by Owen.K

함수포인터

배열의 이름이 배열의 시작 주소 값을 의미하듯, 함수의 이름도 함수가 저장된 메모리 공간의

주소 값을 의미.

함수 포인터를 잘 쓰려면 타입을 추출할 줄 알아야 한다.

type

name

address

void (*)()

test

 

int (*)(const char *format, ...)

printf


 

int *p

void test()

{

int (*fp)(const char *, ...)=printf;        int는 함수의 형

   (*fp)는 포인터 변수 이름

               (const char *, ...)은 함수의 원형 타입

            (*fp)("fuckup \n");                             printf()함수처럼 쓴다.

            printf("test \n");

            return;

}

int main()

{

            void (*fp)();                                      함수 포인터 선언 4byte.

            fp=test;

            test();

<!--[if !supportEmptyParas]-->             return 0;

}

<!--[if !supportEmptyParas]--> (예시1)

(예시2)



(예시3)

(예시4)

<!--[endif]-->

void 포인터

주소 값을 가리키되 어떤 타입인지 가리키고 있지 않다. 고로 타입을 가리지 않는다. 주소 숫자만 가지고 있다. void는 양쪽 디테일한 형 검사는 하지 않는다. 고로 *은 붙이지 못함(따라가지 못한다.)

(예시1)

(예시2)

HexaView1

main7.c

 

HexaView2

 main8.c

 

HaxaView3

main6.c


포인터 대상의 const선언 

포인터 변수가 참조하는 대상의 변경을 허용하지 않는 const선언코드의 안정성을 높이기 위해 사용됨.

int A = 100;

const int B = 100;

int *c = &A;

const int *D = &A;

A=10; //O

B=20; //X

*C=30; //O

*D=40; //X

D=&B; //O

int *const E = &A;

*E = 50; //O

E=&B; //X

const int * const F = &A; 앞에 const*를 꾸며주고, 뒤에 constF를 꾸며줌.

상수 값이 변하지 못함.

*F=60; //X

F=&B; //X


다차원배열의 이해와 활용


// int iaTwo[5];

// printf("%08X \n",iaData);

// printf("%08X \n",iaTwo);

// printf("%08X \n",iaTwo+1);

// printf("%08X \n",&iaTwo+1); //배열 앞에 &를 하면 배열 전체를 뜻한다.

//16진수 14->10진수 20byte를 뛰어넘음.

iaData[0][0]

     
       
       

 

// int iaTwo[5];

// printf("%08X \n",iaData);

// printf("%08X \n",iaTwo);

// printf("%08X \n",iaTwo+1);

// printf("%08X \n",&iaTwo+1); //배열 앞에 &를 하면 배열 전체를 뜻한다.

//16진수 14->10진수 20byte를 뛰어넘음.

 

배열[1] = *(배열+1)

 

*(*(iaData+0)+0) = *(iaData[0]+0) = iaData[0][0] = **iaData

(예시1)

 

 

 (문제1)

 (문제2)

 (문제5일부)