http://www.yes24.com/24/Goods/42800973?Acode=101


실무 프로그래밍 초급편에 문제 풀이를 해 달라는 요청이 있었기에 씁니다.


1. 다음은 실행 가능한 코드입니까? 

#include <stdio.h>

int main()

{

             printf("Hello   World\n");

             extern   int s;

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

             return   0;

}

int s = 88;


실행 가능합니다. 많은 프로그래머가 전역 변수는 함수 밖에서 선언해야 한다는 규칙으로 알고 있고, 인터넷에도 관련해서 잘못된 포스팅이 수십 건은 되는 것 같아서 책에 싣게 되었습니다. 물론, 이 소스 하나로 절차지향 프로그래밍에 대한 개념 설명시 이용하기도 합니다. C는 사실 객체 지향 언어입니다.


2. 다음은 포인터 입니까? 배열 입니까? 

int (*s)[8];


포인터입니다. 8의 크기를 갖는 배열의 주소를 지칭하는 포인터입니다. 실무 프로그래밍을 위해 *, &를 알고 관련 개념 이해를 위해 만든 문제입니다. 

int sora[8] = {0, 1, 2, 3, 4, 5, 6, 7};

int(*s)[8];

s = &sora;

printf("%d", (*s)[2]);

하면 두번째 값이 출력됩니다.



3. 다음 두 코드의 차이점은 무엇입니까? 

int *s();

void (*s)();


전자는 포인터 함수, 후자는 함수 포인터입니다. 전자는 int* s(); 로 int형 포인터를 반환하는 함수의 선언입니다. main() 함수 뒤쪽에 함수 선언 후 printf("%d", *s()); 로 쓸 수 있습니다. s() 로 함수를 실행하면, 주소 값이 넘어 오는데 해당 주소값에 있는 실제값을 * 연산자를 이용해서 보여줄 수 있습니다.

int* s()

{

int soul = 4;

return &soul;

함수 포인터는 반환 값이 같고 인자 선언이 같은 void myFunc() { } 와 같은 함수를 ss = myFunc; 로 지정할 수 있는 포인터입니다. 함수의 주소를 가리키는 포인터입니다.



4. 결괏값은 무엇입니까? 

#include <stdio.h>

int main()

{

             float   s = 3.141592;

             float   *o;

             o   = &s;

             printf("%f\n",   *o);

             printf("%f",   o[0]);

             return   0;

}

같은 값이 나옵니다. 값을 표현하는 연산자인 *와 []의 동일성을 말하기 위한 문제입니다.


5. 결과값은 무엇 입니까? 

#include<stdio.h>

int main()

{

             int   s = 8;

             const   int *o;

             o   = &s;

             *o   = 88;

             printf("%d",   s);

             return   0;

}


실행되지 않습니다. const 는 해당 메모리 주소가 가리키는 곳을 read-only 영역으로 하라는 뜻입니다. read-only 이기에 *o로 8이라는 값을 가져올 수는 있으나 해당 주소에 쓸 수는 없습니다. const 예약어가 없다면 값이 바뀝니다.


6. 결과값은 무엇 입니까? 

#include <stdio.h>

int main() {

             int   s = 3;

             int   o = 4;

             printf("%d",   s^o);

             return   0;

}

OR 연산(011+100)에 의해 7(111)이 됩니다.


7. 결과값은 무엇 입니까? 

#include <stdio.h>

#include <stdlib.h>

int main()

{

             int   *p = (int*)malloc(88 * sizeof(int));

             printf("%d   ", sizeof(p));                           

             return   0;

}


4혹은 8입니다. 포인터 변수의 크기이므로 주소 크기 입니다. 32bit로 컴파일하면 4, 64bit 인 경우 8이 됩니다.


8. 다음에서 typedef 제외, 코드를 재 작성 하십시요. 

typedef struct _Customer {

             char   name[8];

             int   id;

} Customer;

#include <stdio.h>

#include <string.h>

int main() {

             Customer   s, o;

             strcpy_s(s.name,   "Soul");

             s.id   = 8888;

             strcpy_s(o.name,   "Sora");

             o.id   = 3333;

             printf("name   : %s %s\n", s.name, o.name);     

             printf("id   : %d %d", s.id, o.id);

             return   0;

}

typedef를 제외하면, Customer s, o가 아닌 struct _Customer s, o로 쓰면 됩니다. 보통 typedef struct { 로 바로 씁니다. struct 선언 문법을 헷갈리게 하려고 한 의도입니다. struct 를 잘쓰면 class 부럽지 않습니다. 물론, 메소드(멤버함수, 함수)는 함께 담을 수 없지만 말이죠.


9. 결과값은 무엇 입니까? 

#include<stdio.h>

void main()

{            

             int   i = 0;

             printf("%d   ", i++);

             main();

}

 네, 0이 나오는 무한 루프 입니다. 실무 프로그래밍 초급편에서 main 함수를 호출하는 함수 포인터를 만들고, 무한 루프를 탈출할 수 있는 방법을 연구해 보았습니다.


10. 결과값은 무엇 입니까? 

#include<stdio.h>

union {

             char   s[3];

             int   o;     

} _union;

struct {

             char   r[3];

             int   a;

} _struct;

int main() {        

             printf("%d   %d\n", sizeof _union.s, sizeof _struct.r);

             printf("%d   %d\n", sizeof _union.o, sizeof _struct.a);

             printf("%d   %d", sizeof _union, sizeof _struct);

}


3 3

4 4

4 8

입니다. struct는 메모리를 공유하지 않고 내부에 묶여진 자료형에 대해서 각각 공간을 할당합니다. union의 경우 가장 큰 타입의 메모리의 크기를 가진다고 알려져 있습니다. 메모리를 공유하는 것은 맞지만 가장 큰 메모리를 점유하는 것은 아닙니다. 가장 큰 자료형의 "배수"가 들어갈 공간을 확보합니다. 가령,

union {

char   s[11];

int   o;

} _union;

의 경우, s배열 크기 char*11을 담을 11이여야 할 것 같지만 12가 나옵니다. o가 double일 경우 16이 나옵니다. char s[11]이 가장 크지만 해당 크기만큼만 메모리를 할당하지 않습니다. double형의 2배만큼 할당합니다(. comm   _union,16,16).  struct도 마찬가지 결과입니다. 이론과 실무는 많이 다릅니다.


+ Recent posts