" async="async"> ', { cookie_domain: 'auto', cookie_flags: 'max-age=0;domain=.tistory.com', cookie_expires: 7 * 24 * 60 * 60 // 7 days, in seconds }); 책 알려주는 남자 :: 책 알려주는 남자

13장 Summary


구조체와 배열의 차이점은 묶는 료형들의 일치여부이다.

구조체는 키워드 struct으로 선언하고 공용체는 union, 열거형은 enum으로 선언한다.

구조체의 선언만으로 변수가 만들어지는가? 아니다. 따로 변수의 선언이 필요하다

구조체를 가리키는 포인터 p를 통하여 구조체 안의 변수 x를 참조하는 수식은
(*p).x 또는 p->x
이다.

원본 구조체를 포인터로 함수에 전달하는 경우, 원본 구조체를 훼손하지 않게 하려면 어떻게 하면 되는가? const 키워드가 포인터 앞에 있으면 이 포인터가 가리키는 구조체의 값을 변경하려고 하면 오류메시지가 뜬다. 즉 원본수정이 불가능하게 되어 원본이 훼손되지 않는다


 union data{

   double d;
   int i;

  };

union 은 다른 타입의 변수들이 동일한 기억 공간을 공유할 수 있도록 만든 것이다. 때문에 동시에 모든 멤버 변수들의 값을 저장할 수 없으며 어떤 순간에는 하나의 멤버만 존재할 수 있다


  enum color { red, green, blue};

  enum color favorite = red; 

enum 은 정수형 상수값들을 나열해 놓은 자료형이다.

#define 대신에 열거형을 사용하는 장점은 무엇인가? 특정한 숫자 대신 기호를 사용함으로써 프로그램의 이해도를 향상 시킬 수 있고, 변수가 열거된 값 이외의 값을 취하는 것을 막아서 오류를 줄여준다


   typedef long int BIGINT;

   BIGINT i; 

새로운 자료형을 정의하기 위하여 사용되는 키워드는 typedef이다.

블로그 이미지

얼음꿀차

책을 한 번 읽긴 읽어야겠는데 막상 읽자니 뭘 읽을지 고민되는 당신을 위해 읽을만한 책들을 알려드립니다!

,

13장 Exercise


1. 구조체를 정의하고 c1이라는 이름의 구조체 변수를 정의하시오.

struct customer {

char name;

int post_num;

long mileage;

};

struct customer c1;


2. T/F

(a) 구조체를 선언하면 자동으로 변수가 생성된다. F
(b) typedef은 변수를 선언하는 키워드이다. F, 변수가 아니라 자료형이다
(c) 구조체는 ==연산자를 사용하여 비교할 수 있다. T
(d) 구조체를 함수로 전달하면 원본이 전달된다.   F, 복사본이 전달된다
(e) 구조체 변수는 =연산자를 이용하여 대입될 수 있다. T

비고) 대입의 경우 p1=p2나 p1.x=p2.x, p1.y=p2.y 모두 가능하다. 하지만 비교의 경우 p1==p2는 불가능하고 p1.x==p2.x && p1.y==p2.y 가 가능하다


3. Employee 구조체로 정의된 변수 e에는 salary라는 필드가 있다. 이 필드를 올바르게 참조한 것은?

②e.salary


4. 포인터 p는 Employee 구조체로 정의된 변수 e를 가리킨다. 올바르게 참조한것은?

① p->salary ③ (*p).salary


5. 다음 열거형의 정의를 보고 각 식별자의 정수값을 예측하여 보라.

enum colors {white, red=3, blue, green, black=9 };

 식별자 

 white 

 red 

 blue 

 green 

 black 

 값

 0

 3 

 4 

 5 

 9 

비고) 0부터 혹은 지정된 값으로부터 자동적으로 1씩 증가한다.


6. 다음과 같은 구조체 정의가 있는 경우에 올바른 문장을 모두 골라라

   struct STU{

        char name[30];
        int id;

    } s; 

 ①②③⑤⑦⑧⑥


7. 잠시 컴파일러가 되어보자. 다음 코드에서 오류가 있는 것은?

   union id{

        char name[4];

        long number;

   } var={"Tom", 1}; 

초기화 할 시 한 번에 하나의 멤버만 사용이 되기 때문에  첫 번째 멤버만 초기화된다. 따라서 var={"Tom"}; 으로 바꾸어야 한다.


8. 다음의 설명에 부합하는 구조체를 정의하여 보라.

(a) char title[30]과 int pub_date, pages, price를 포함하는 구조체 book

struct book{

      char title[30];
      int pub_date;
      int pages;
      int price;

};

(b) char name[30], int age, double height를 포함하는 구조체 friend

struct friend{

      char name[30];
      int age;
      double height;

};

(c) 이름, 수량, 가격으로 부품 재고를 표현하는 구조체 part 정의

struct part{

      char name[20];
      int ea;
      int price;

};


9. 다음의 설명에 부합하는 열거형을 정의하여 보라

(a) 빛의 3원색을 표현하는 열거형 primary_color

enum primary_color { RED, GREEN, BLUE };

(b) 12달을 표현하는 열거형 months 정의

enum months { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC};

  


10. 다음 코드가 오류를 가지고 있는지를 먼저 분석하고 오류가 있다면 어떤 오류인지 설명하라.

 (a) 

 struct book{

    char title[50];
    int pages;

 };

 book.pages = 512;


 struct book{ 

    char title[50];
    int pages;

 }; book;

 book.pages = 512;


 (b) 

 struct book{

     char title[50]="Data Structures";
     int pages = 577;

 } abook;

 struct book{

      char title[50];
      int pages;

 }; abook = {"Data Structures", 577};

 (c)

 typedef enum { red, green, blue } color;

 color.red = 1;

 typedef enum color { red=1, green, blue };

 (d)

 struct fraction {

     int num;
     int den;

  } *p;

  *p->num = 3;
  *p->den = 5;

 struct fration {

      int num;
      int den;

 } s = {3, 5};

 struct fration p;

 p=&s;



블로그 이미지

얼음꿀차

책을 한 번 읽긴 읽어야겠는데 막상 읽자니 뭘 읽을지 고민되는 당신을 위해 읽을만한 책들을 알려드립니다!

,

12장 Programming


1.

#include <stdio.h>


void main(){

char c;

printf("문자를 입력하시오: ");

scanf("%c", &c);

printf("아스키 코드값=%d", c);

}


2.

#include <stdio.h>


void space_delete(char *str);


void main(){

char str[100];

printf("공백 문자가 있는 문자열을 입력하시오: ");

gets(str);

space_delete(str);

}


void space_delete(char *str){

int i=0;

while(str[i]!=NULL){

if(str[i]!=' ')

printf("%c", str[i]);

i++;

}

}


3.

#include <stdio.h>


int str_chr(char *s, int c);


void main(){

char s[100];

char c;

printf("문자열을 입력하시오: ");

gets(s);

printf("개수를 셀 문자를 입력하시오: ");

scanf("%c", &c); 

printf("%c의 개수 : %d", c, str_chr(s, c));

}


int str_chr(char *s, int c){

int i, count=0;

for(i=0; s[i]!=NULL; i++){

if(s[i]==c)

count++;

}

return count;

}


4.

#include <stdio.h>


int str_chr(char *s, int c);

void count_chr(char *s);


void main(){

char s[100];

char c;

printf("문자열을 입력하시오: ");

gets(s);

count_chr(s);

}


int str_chr(char *s, int c){

int i, count=0;

for(i=0; s[i]!=NULL; i++){

if(s[i]==c)

count++;

}

return count;

}


void count_chr(char *s){

int i;

for(i='a'; i<='z'; i++)

printf("%c: %d\n", i, str_chr(s,i));

}


5.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>


void upper_lower(int c);


void main(){

int c;

printf("문자를 입력하시오: ");

while((c=getchar())!='.'){

fflush(stdin);

if(islower(c)){

c=toupper(c);

putchar(c);

}

else if (isupper(c)){

c=tolower(c);

putchar(c);

}

printf("\n");

printf("문자를 입력하시오: ");

}

}


6.

#include <stdio.h>


void str_upper(char *s);


void main(){

char s[100];

printf("문자열을 입력하시오: ");

gets(s);

str_upper(s); 

printf("변화된 문자열: ");

puts(s);

}


void str_upper(char *s){

int i;

for(i=0; s[i]!=NULL; i++)

if(s[i]>='a' && s[i]<='z')

s[i] += 'A' - 'a';

}


7.

#include <stdio.h>

#include <string.h>


int get_response(char *prompt);


void main(){

char prompt[10];

printf("게임을 하시겠습니까? ");

gets(prompt);

if(get_response(prompt)==1)

printf("긍정적인 답변");

else

printf("부정적인 답변");

}


int get_response(char *prompt){

strlwr(prompt);

if(strcmp(prompt, "no")==0)

return 0;

else if (strcmp(prompt, "yes")==0 || strcmp(prompt, "ok")==0)

return 1;


8.

#include <stdio.h>

#include <string.h>


int count(char *str);

char *token;

void main(){

char str[100];

printf("문자열을 입력하시오: ");

gets(str);

printf("단어의 수는 %d입니다.", count(str));

}


int count(char *str){

int count=1;

token = strtok(str, " ");

while(token!=NULL){

count++;

token=strtok(NULL, " ");

}

return count;

}



9.

#include <stdio.h>

#include <string.h>


char check_upper(char *str);

char check_punct(char *str);


void main(){

char str[100];

printf("텍스트를 입력하시오: ");

gets(str);

check_upper(str);

check_punct(str);

printf("결과 텍스트 출력: %s", str); 

}


char check_upper(char *str){

if(islower(str[0]))

str[0]=toupper(str[0]);

return str;

}


char check_punct(char *str){

if(ispunct(str[strlen(str)-1])==0)

str[strlen(str)]='.';

return str;

}


10.

#include <stdio.h>

#include <string.h>


int check_palindrome(char *str);


void main(){

char str[100];

printf("문자열을 입력하시오: ");

gets(str);

strupr(str);

if(check_palindrome(str)==0)

printf("회문입니다.");

else 

printf("회문이 아닙니다."); 

}


int check_palindrome(char *str){

int i, count=0;

for(i=0; i<strlen(str)/2; i++){

if(str[i]==str[strlen(str)-1-i])

count+=0;

else

count+=1;

}

return count;

}


11.  ★★★★

#include <stdio.h>

#include <string.h>

#include <stdlib.h>


void main(){

char str[100];

char *word[100];            // 배열이 아니라 포인터배열이여야만 여러글자를 한 칸에 넣을 수 있다. 주소지(여기서는 token)를 가르키는 방법으로 && 저장될 곳을 미리 할당해주어야 한다.

char *token;

int i, count=0;

printf("문자열을 입력하시오: ");

fgets(str, sizeof(str), stdin);

str[strlen(str)-1] = NULL;    // 남은 빈칸에 쓰레기값이 들어가는 것을 방지함

token = strtok(str, " ");

for(i=0; token!=NULL; i++){

word[i] = token;        // 문자열에서 찾은 마지막 토큰의 주소값을 리턴하며 토큰이 더이상 없다면 NULL 포인터를 리턴한다. 

token = strtok(NULL, " ");

count++;

}

printf("출력문자열: ");

for(i=0; i<count; i++){

printf("%s ", word[count-i-1]);

}


비고) scanf함수는 공백, \t, \n이 오기 전까지의 의미있는 값들을 받는 함수이다. 즉 중간에 띄어쓰기가 있다면 scanf는 띄어쓰기가 포함된 모든 문자열을 입력값으로 받는 것이 아니라 첫번째 띄어쓰기 전까지의 입력값만을 받고 나머지는 버퍼stdin에 저장된다. 문제에서 요구하는 '엔터키가 눌려질 때까지 사용자로부터 문자열을 입력받아서' 라는 문장의 의미는 \n이 오기 전까지 공백과 \t이 포함된 문자열을 받는 fgets함수를 사용하라는 의미이다.  scanf함수의 복잡성을 알지 못한다면 다소 이해하기 어려운 문제이다.

기본형식: char *fgets(char *str, int num, FILE*stream);

 scanf 함수의 앞부분을 생략하는 것처럼 처음의 char * 은 보통 생략한다. 첫 번째 인자는 저장할 배열을 의미한다. 두 번째 인자는 마지막 NULL문자를 포함하여 읽어들일 문자의 수를 의미한다. 세 번째 인자는 문자열을 받아들일 스트림의 FILE 객체를 가르키는 포인터이다. 보통 표준입력에서 입력을 받기때문에 대개 stdin을 쓴다.

성공적으로 읽어드렸다면 함수는 str을 반환하고 오류가 발생하거나 아무것도 읽어드리지 못했다면 NULL 포인터를 반환한다.


12. 

#include <stdio.h>

#include <string.h>


char get_punct(str);


void main(){

char str[100];

char *name[100];

char *token;

char seps[]=" ";

int i, count=0;

printf("영어 이름을 입력하시오: ");

fgets(str, sizeof(str), stdin);

strlwr(str);

str[strlen(str)-1]=NULL;

token = strtok(str, seps);

for(i=0; token!=NULL; i++){

name[i]=token;

token=strtok(NULL, seps);

count++;

printf("변환된 이름: %s %s, %s", name[1], name[2], name[0]);

}


13.

#include <stdio.h>

#include <string.h>


void main(){

char str[100];

int i, count=0;

printf("텍스트를 입력하시오: ");

fgets(str, sizeof(str), stdin);

str[strlen(str)-1]=NULL;

for(i=0; str[i]!=NULL; i++)

if(str[i]=='.' || str[i]==',')

count++;

printf("구두점의 갯수는 %d개입니다.", count);  

}


14. ★★

#include <stdio.h>

#include <string.h>


void main(){

char str[80];

char word1[10];

char word2[10];

char *token;

char *str2[80];

int i, count=0;

printf("문자열을 입력하시오(최대 80자): ");

fgets(str, sizeof(str), stdin);

str[strlen(str)-1]=NULL;

printf("찾을 문자열: ");

fgets(word1, sizeof(word1), stdin);

word1[strlen(word1)-1]=NULL;

printf("바꿀 문자열: ");

fgets(word2, sizeof(word2), stdin);

word2[strlen(word2)-1]=NULL;

token = strtok(str, " ");

for(i=0; token!=NULL; i++){

str2[i]=token;

token=strtok(NULL, " ");

count++;

for(i=0; i<count; i++)

if(strcmp(word1, str2[i])==0)

str2[i] = word2;

printf("결과: ");

for(i=0; i<count; i++)

printf("%s ", str2[i]);

}


15.

#include <stdio.h>

#include <string.h>


void main(){

char str[3];

int x, y, result;

printf("연산을 입력하시오: ");

scanf("%s %d %d", &str, &x, &y);

if(strcmp(str, "add")==0) result=x+y;

else if(strcmp(str, "sub")==0) result=x-y;

else if(strcmp(str, "mul")==0) result=x*y;

else if(strcmp(str, "div")==0) result=x/y;

printf("연산의 결과: %d", result);

}


16. ★★★

(a) 매 반복마다 실제로 문자 배열의 내용을 수정


(b) 포인터를 이용하여 현재 위치에서 일정길이만큼 화면 표시

블로그 이미지

얼음꿀차

책을 한 번 읽긴 읽어야겠는데 막상 읽자니 뭘 읽을지 고민되는 당신을 위해 읽을만한 책들을 알려드립니다!

,

12장 Exercise


1. 

(a) strcat() 함수는 하나의 문자열의 끝에 다른 문자열을 연결한다. 
(b) strcpy() 함수는 문자열을 복사한다.
(c) strtok() 함수는 문자열에서 토큰을 찾는다.
(d) gets() 함수는 표준입력에서 하나의 문자열을 읽는다.
(e) strlen() 함수는 문자열을 이루는 문자의 개수를 반환한다.


2. 오류있을 시 정정하라

(a) strcat(s, '?');

 (a) strcats(s, "?");

 (b) if( s!="value")

 (b) if(strcmp(s1, "value") !=0

 (c) char a[20];
     a="Hello World!";

 (c) char a[20];
     strcpy(a, "Hello World!");

     또는

     char *a;
     a="Hello World!";



3. 다음 문장이 제대로 동작하지 않은 이유 및 수정방안

  char *s1 = "Hi ";
  char *s2 = "Programmers!";
  char *s3 = strcat(s2, s2); 

 *s1의 공간은 NULL을 포함해 3byte뿐이다. 이어 붙일 공간이 부족하기 때문에 동작하지 않는다.

 char s1[100] = "Hi ";


4. 다음 두 문장의 차이점을 설명하라

  char a[] = "Hello World!";
  strcpy(a, "Goodbye"); 

  char *p = "Hello World!";
  p = "Goodbye";

비고) 문자열 변경에 있어서 방법이 다르다.


5. 두개의 문자열이 일치하는지를 검사하는 문장을 올바르게 작성한 것은?

④if( strcmp(s1, "Hello") == 0)


6. 오류있을 시 정정하라

 int main(){

     char *p;

     scanf("%s", p);

  } 

 int main(){

    char *p=malloc(sizeof(char)*10);

    scanf("%s", p);

  } 

비교 ) 문자열 포인터에 입력값을 받을 때, 문자열을 받을 수 있을 만큼 메모리를 할당해 주어야 한다. 


7. 다음의 변수들에게 몇 바이트의 메모리가 할당되는가?

 (a) char str[] = "abc"; 

  4 bytes

 (b) char *pc = "abc";

  4 bytes

 (c) char str[10] = "abc";

  10 bytes

 (d) char str[2][10] = {"abc", "def"};

  20 bytes


8. 다음의 수식값을 말하여라

char s[][10] = {"HIGH", "MIDDLE", "LOW"};

(a) s[0] = HIGH

(b) s[1][3] =D

(c) *S = HIGH


9. 다음 코드의 실행결과를 써라

void main()

{

char *p;

char s[]="Hello";

p=s+strlen(s) -1;

while(p>=s){

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

p--;

}

}


실행결과) 

o
lo
llo
ello
Hello

비고) 처음 p=s+4이고 반복될 때마다 1씩 줄어든다. 

처음엔 s+4인 지점부터의 문자열을 프린트해서 o가 나오고

그 다음엔 s+3인 지점부터 문자열을 프린트해서  lo가 나온다.

이런식으로 반복하여 마지막엔 s의 문자열 전체가 나온다.



10. 다음의 함수가 하는 작업은 무엇인가? 구체적으로 mystery("abc", "abd")와 같이 호출하면 어떤 값이 반환되는가?

#include <stdio.h>


int mystery(const char *s1, const char *s2){

while(*s1==*s2){

if(*s1==0)

return (0);

s1++; 

s2++;

}

return (1);

}


void main(){

int result;

result = mystery("abc", "abd");

printf("%d", result);

}


실행결과) 1

비고) 두 개의 문자열 상수가 일치하는지를 검사하는 함수이다. 일치한다면 0으로 반환될 것이고 한 문자라도 틀리면 1로 반환될 것이다.

블로그 이미지

얼음꿀차

책을 한 번 읽긴 읽어야겠는데 막상 읽자니 뭘 읽을지 고민되는 당신을 위해 읽을만한 책들을 알려드립니다!

,