'sizeof'에 해당되는 글 2건

Programming/C C++
1. 산술연산자

 연산자  역활
 +  더하기
 -  빼기
 *  곱하기
 /  나누기
 %  나머지

#include <stdio.h>

main()
{
  int i;
  int j;
 
  i = 3;
  j = 2;
 
  printf("%d\n", i + j);
  printf("%d\n", i - j);
  printf("%d\n", i * j);
  printf("%d\n", i / j);
  printf("%d\n", i % j);
}



2. 관계연산자

 연산자  역활
 <  작다.
 >  크다.
 ==  같다.
 <=  작거나 같다.
 >=  크거나 같다.
 !=  같지않다.

#include <stdio.h>

main()
{
  int i;
  int j;
 
  i = 3;
  j = 2;
 
  if (i < j)
    printf("i가 j보다 작다.\n");
  
  if (i > j)
    printf("i가 j보다 크다.\n");
   
  if (i == j)
    printf("i와 j가 같다.\n");
   
  if (i != j)
    printf("i와 j가 같지않다.\n");
}



3. 관계연산자의 또다른 정의 방법

관계연산자를 통해 다음과 같은 구문이 작성하였습니다.

#include <stdio.h>

main()
{
  int i = 2;
  int j = 1;
  int t;
 
  if (i < j)
    t = i + j;
  else
    t = i - j;
   
  printf("결과 : %d\n", t);
}


위 program은 i가 j보다 작으면 i와 j를 더하여 t에 저장하고 i가 j보다 작지 않으면 i에서 j를 뺀 후 그 결과를 t에 저장하도록 하고 있습니다. 만일 위와 같은 조건식이 복잡하다고 생각되면 다음과 같이 작성하는 것도 가능합니다.

#include <stdio.h>

main()
{
  int i = 2;
  int j = 1;
  int t;
 
  t = (i < j) ? i + j : i - j;
   
  printf("결과 : %d\n", t);
}


'조건 ? 참일경우의 처리 : 거짓일 경우의 처리;' 의 형식으로 작성하면 위와 같은 조건식을 조금이나마 더 간단하게 표현할 수 있게 됩니다.

4. 논리연산자

 연산자  역활
 !  부정
 &&  그리고(and)
 ||  또는(or)

#include <stdio.h>

main()
{
  int i = 10;
  int j = 20;
 
  int a = 15;
  int b = 20;
 
  if ((i < j) && (a < b))
    printf("i가 j보다 작고 a가 b보다 작다.\n");
   
  if ((i < j) || (a > b))
    printf("i가 j보다 작거나 a가 b보다 크다.\n");
   
  if (!(i == a))
    printf("i가 a와 같지 않다.(i != a)와 같다.\n");
}



5. 대입연산자

 연산자  역활
 =  우변값을 좌변에 대입
 +=  좌변값과 우변값을 더한 후 좌변에 대입
 -=  좌변값에 우변값을 뺀 후 좌변에 대입
 *=  좌변값과 우변값을 곱한 후 좌변에 대입
 /=  좌변값과 우변값을 나눈 후 좌변에 대입
 %=  좌변값과 우변값을 나누고 그 나머지를 자변에 대입
 >>=  좌변값을 우변값만큼 오른쪽 shift연산 후 좌변에 대입
 <<=  좌변값을 우변값만큼 왼족 shift연산 후 좌변에 대입
 &=  좌변값과 우변값을 and연산 후 좌변에 대입
 |=  좌변값과 우변값을 or연산 후 좌변에 대입
 ^=  좌변값과 우변값을 xor연산 후 좌변에 대입

#include <stdio.h>

main()
{
  int i = 10;
  int j = 20;
 
  i = j;
  printf("j값을 i변수에 대입 %d\n", i);
 
  i += j;
  printf("i와 j를 더하고 그 결과를 i에 대입 %d\n", i);
 
  i -= j;
  printf("i에 j값을 감산한 후 그 결과를 i에 대입 %d\n", i);
 
  i *= j;
  printf("i와 j를 곱하고 그 결과를 i에 대입 %d\n", i);
 
  i /= j;
  printf("i와 j를 나누고 그 결과를 i에 대입(정수결과값 반환) %d\n", i);
 
  i = 10;
  j = 3;
 
  i %= j;
  printf("i와 j에 대한 나머지 결과를 i에 대입 %d\n", i);
 
  i = 5;
  j = 1;
 
  i >>= j;
  printf("i값을 j만큼 오른쪽 shift한 후 i에 대입 %d\n", i);
 
  i <<= j;
  printf("i값을 j만큼 왼쪽 shift한 후 i에 대입 %d\n", i);
 
  i = 3;
  j = 2;
 
  i &= j;
  printf("i값과 j값을 and연산(bit 기준) %d\n", i);
 
  i = 2;
  j = 3;
 
  i |= j;
  printf("i값과 j값을 or연산(bit 기준) %d\n", i);
 
  i = 2;
  j = 4;
 
  i ^= j;
  printf("i값과 j값을 xor연산(bit 기준) %d\n", i);
}



6. Shift연산

인간의 입장에서 가장 많이 쓰이는 숫자는 10진수입니다. 그에 반해 Computer는 0과 1만으로 이루어진 2진수를 씁니다. 0과 1만으로 Data를 처리하기가 가장 간단하기 때문에 그 만큼 단순화할 수 있기 때문입니다. 2진수를 10진수로 이해하기 위한 방법중의 하나로 2진수 각 자리를 2의 승수로 계산하는 방법이 있습니다. 예를 들어

10

이라는 2진수가 있으면 각 자리를 오른쪽 부터 20, 21순으로 계산하여 2 * 0, 2 * 1 을 하게되면 2 * 1에만 1이 있으므로 10진수로 2가 되는 것입니다.

Shift연산이라는 것은 이 2진수로 나열된 숫자를 밀어버리거나 당겨놓는 것을 의미하는 것으로 C언어를 통해

5 >>= 1

이라고 하면 '5를 2진수화 한 기준에서 1만큼 오른쪽으로 민다.'라는 의미가 됩니다. 따라서 5를 2진수로 분해하면

101

이 되고 이 상태에서 오른쪽으로 1만큼 밀면 결과는

10

이 됩니다.

마지막으로 이 10이라는 2진수를 10진수로 바꾸면 다음과 같은 결과가 생기게 됩니다.(왼쪽 Shift연산을 하면 0이 채워지게 됩니다.)

2

Shift연산자는 필요하다면 몇개든 사용할 수 있습니다.

5 >> 4 << 3 >> 2

7. and, or, xor연산

and연산은 연산하고자 하는 피연산자의 bit가 1일때만 1이 되는 연산입니다. 참고로 and와 or, xor연산도 Shift연산처럼 2진수를 기준으로 연산합니다.

10진수 3을 2진수로 -> 11
10진수 2를 2진수로 -> 10

11과 10을 and연산하면 1이 있는 것만 1이되므로 결과는 10(10진수 2)이 됩니다.

and는 피연산자가 모두 1이여야만 결과가 1이지만 or연산자는 둘줄 하나만 1이여도 결과가 1이 됩니다.

10진수 2를 2진수로 -> 10
10진수 3을 2진수로 -> 11

10과 11을 or연산하면 둘중 하나만 1이 있어도 1이되므로 결과는 11(10진수 3)이 됩니다.

and와 or는 피연산값이 1인가 0인가에 따라 결과가 달라지지만 xor는 피연산자값이 같은가 틀린가에 따라 결과가 달라집니다.

10진수 2를 2진수로 ->  10
10진수 4를 2진수로 -> 100

10과 100을 xor연산하면 처음 두자리 까지는 상호 값이 다르므로 1이고(비어있는 부분은 자동으로 0이 됩니다.) 마지막 한자리는 둘다 값이 0이므로 연산값은 0이 됩니다. 따라서 결과는 110 (10진수 6)이 됩니다.

참고 :
산술연산자와 Shift연산자, and/or/xor연산자는 모두 뒤에 =기호가 붙어있어서 대입관련 연산자가 되지만 =기호만 빼면 각각의 역활을 별도로 수행하는 연산기호가 됩니다.(and, or, xor연산자는 모두합쳐 bit연산자라고도 합니다.)

8. sizeof 연산자

sizeof는 특정 Data형의 크기값을 반환하는 연산자중의 하나입니다.

#include <stdio.h>

main()
{
  int i;
 
  printf("int형 크기 : %d\n", sizeof(i));
}



9. cast 연산자

특정 Data형을 다른 Data형으로 변환하기 위한 연산자입니다.

#include <stdio.h>

main()
{
  int i = 10;
  
  printf("%f\n", (float)i);
}


(float)i 를 통하여 int형 변수 i를 float형으로 변환하여 출력합니다.


참고 :
Data형이 작은 것과 Data형이 큰것끼리 큰 Data형을 기준으로 연산하게 되면 자동 형변환되어 연산됩니다.

#include <stdio.h>

main()
{
  char c = 10;
  int i = 1000;
 
  printf("%d\n", c + i);
}



10. 증/가감 연산자

 연산자  역활
 ++  1더한다.
 --  1뺀다.

증/가감 연산자는 피연산자의 값을 1증가하거나 1감소시키는 역활을 합니다.

#include <stdio.h>

main()
{
  int i = 1;
 
  ++i;
 
  printf("%d\n", i);
}



하지만 ++나 --연산자가 다른 연산자와 함께 연산되는 경우 증/가감연산자가 앞에 있으면 선증가/선감소 되고 뒤에 있으면 후증가/후감소되어 약간씩 다른 결과를 나타낼 수도 있습니다.

예를 들어

int i = 100;
int j;
j = ++i - 50;

라고 하면 ++연산자가 앞에 있으므로 먼저 i값을 1증가 시킨 후 - 50을 계산하게 됩니다. 반면

int i = 100;
int j;
j = i++ - 50;

위와 같이 ++가 피연산자의 뒤에 위치하게 되면 먼저 - 50을 계산한 후에 i값을 1증가시키게 됩니다.

#include <stdio.h>

main()
{
  int i = 100;
  int j;
 
  j = ++i - 50;
  printf("%d\n", i);
  printf("%d\n", j);
 
  i = 100;
 
  j = i++ - 50;
 
  printf("%d\n", i);
  printf("%d\n", j);
}



11. bit 연산자

 연산자  역활
 &  and 연산
 |  or 연산
 ^  xor 연산
 ~  반전

bit연산자는 피연산자의 bit부호를 가지고 연산을 수행하는 연산자 입니다.

#include <stdio.h>

main()
{
 char i = 5;
 char j = 4;
 i = i & j;
 printf("%d\n", i);
}


i의 값과 j의 값을 &(and) 연산합니다.

먼저 &(and)연산은 두 bit가 1이되야만 결과가 1이 되는 연산입니다. i의 5와 j의 4라는 값을 bit로 분해해 보면 다음과 같이 되며(Char 형은 8bit크기(128)의 Data형입니다.)

i 값 5 => 00000101
j 값 4 => 00000100

bit값 중에서 같은 위치에 둘다 1인것은 뒤에서 세번째 bit밖에 없으므로 and연산의 결과는

00000100 => 정수값 4

가 되는 것입니다.


#include <stdio.h>

main()
{
 char i = 5;
 char j = 4;
 i = i | j;
 printf("%d\n", i);
}


i와 j값을 |(or) 연산합니다.

|(or)연산은 두개의 피연산자중 하나만 1이여도 결과가 1이되는 연산입니다.

5 => 00000101
4 => 00000100
-------------
결과 00000101 (5)


#include <stdio.h>

main()
{
 char i = 5;
 char j = 4;
 i = i ^ j;
 printf("%d\n", i);
}


i와 j값을 ^(xor)연산합니다.

^(xor)연산은 두 피연산자가 0이든 1이든 서로 다른 값을 가져야만 결과가 1이되는 연산입니다.

5 => 00000101
4 => 00000100
-------------
결과 00000001 (1)


#include <stdio.h>

main()
{
 char i = 128;
 
 i = ~i;
 printf("%d\n", i);
}


i값의 모든 bit를 반전시킵니다.

~연산은 피연산자의 bit를 모두 반전시키는 연산자입니다.

128 => 10000000
---------------
반전    01111111 (127)

'Programming > C C++' 카테고리의 다른 글

[C, C++] Object(obj)와 Link  (0) 2011.02.10
[C, C++] 상수(숫자, 문자, 문자열, 열거형) 정의및 사용  (0) 2011.02.09
[C, C++] 연산자  (0) 2011.02.08
[C, C++] 제어문  (0) 2011.02.01
[C, C++] 공용체  (0) 2010.09.27
[C, C++] Volatile  (0) 2010.09.15
0 0
Programming/C C++
 1. malloc

C언어에서 동적으로 Memory를 할당하려면 malloc함수를 이용합니다. 이 함수는 인수로 전달된 정수만큼의 byte크기를 Memory에서 할당하고(만일 할당에 실패하면 NULL을 반환합니다.) 할당된 Memory주소를 Pointer로 반환합니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
 
  p = (char *)malloc(10);
}


10 byte의 Memory확보 후 해당 Memory위치를 Pointer p에 되돌립니다.

참고 :
malloc()함수사용시 반환부분에 (char *)형으로 변환시켜 주는 이유는 malloc()함수가 Memory를 확보한 후 해당 Pointer를 반환할때 형이 없는 void(*)를 반환하기 때문입니다. 이는 반환되는 Memory영역을 범용적으로 활용하기 위해서 입니다.

malloc()함수를 이용하면 구조체와 결합하여 해당 구조체를 동적으로 할당하고 할당된 구조체를 연결시킴으로서 연결 List를 생성할 수 있습니다.(연결 list라는 것은 같은 데이터형이 기차처럼 연결된 형태를 지닌다고 하여 붙여진 이름입니다.)

다음 Program은 구조체와 malloc()함수를 사용해 동적으로 구조체에 대한 Memory를 할당하고 연결 List를 생성한 예제입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
  struct student{
    char name[5];
    int kuk;
    int eng;
   
    struct student *np;
  };
  struct student *p;
 
  p = (struct student *)malloc(sizeof(struct student));
 
  strcpy(p->name, "kim");
  p->kuk = 80;
  p->eng = 90;
 
  p->np = (struct student *)malloc(sizeof(struct student));
 
  strcpy(p->np->name, "choi");
  p->np->kuk = 90;
  p->np->eng = 100;
 
  printf("%s : kuk - %d, eng - %d\n", p->name, p->kuk, p->eng);
  printf("%s : kuk - %d, eng - %d\n", p->np->name, p->np->kuk, p->np->eng);
  free(p);
  free(p->np);
}


일단 Header File에서 stdlib.h는 malloc()함수 사용을 위해 선언되었으며 string.h는 strcpy()함수 사용을 위해 선언되었습니다.

다음은 구조체 선언부분입니다.

struct student{
    char name[5];
    int kuk;
    int eng;
   
    struct student *np;
};

struct로 구조체가 student라는 이름으로 선언되었습니다. 이 구조체는 학생의 점수관리를 위한 구조체로 학생의 이름과 국어점수 그리고 영어점수를 저장할 수 있도록 name과 kuk, eng Member로 구성되어 있습니다.

그리고 마지막 member에는 struct student *np;가 있는데 이는 자기 자신을 가리키는 Pointer를 Memeber(자기참조 구조체)로 가지기 위해서 존재합니다.

이 자기참조 구조체는 동적으로 같은 구조체가 Memory에서 생성될때 그 구조체의 시작주소를 갖게 됨으로서 자연스럽게 구조체간 연결 List를 이루도록 하는 것입니다.

구조체 선언 다음에는 구조체에 접근하기 위해 해당 구조체 Data형의 Pointer변수를 선언하였습니다.

struct student *p;

구조체와 Pointer를 선언하고 malloc()함수를 호출하여 구조체크기 만큼의 Memory를 동적으로 생성하도록 합니다.

p = (struct student *)malloc(sizeof(struct student));

보시는 바와 같이 malloc함수안에 sizeof함수가 사용되었습니다. 이 sizeof함수는 인수로 student구조체를 전달하고 그 크기만큼의 Byte값을 정수형태로 반환합니다. 그러면 malloc함수는 반환되는 값 만큼 Memory를 확보하고 그 수행 결과로 Memory의 시작주소를 Pointer p에 반환합니다.(이때 반환되는 Data형은 void형이므로 해당 Data형을 student 구조체로 변환해야 합니다.)

이렇게 Pointer p는 student구조체 형식으로 확보된 Memory시작 주소값을 가지게 됩니다.


이제 Pointer p를 이용해 학생의 이름과 점수를 Memory영역에 담아봅시다.

strcpy(p->name, "kim");
p->kuk = 80;
p->eng = 90;

Pointer에서 -> 를 사용하여 각 Member에 접근합니다. 그리고 kim이라는 이름과 국어점수 80점, 영어점수 90점을 저장합니다.

이때 학생은 단 한명이 아니라 2명 세명.. 그 이상도 될지 모르기 때문에 미리 일정한 구조체를 선언해 두는 것은 그리 좋은 선택이 아닐 것입니다. 따라서 이런경우 동적으로 할당한다는 개념이 필요하게 됩니다.

학생수가 늘어나면 그 만큼 더 많은 구조체가 할당되어야 하기 때문에 처음 구조체의 자기참조 구조체에 동적으로 할당한 다른 구조체의 Memory주소를 갖게 함으로서 연결 list형의 구조를 이루도록 하려 합니다.

p->np = (struct student *)malloc(sizeof(struct student));

p->np를 통해 구조체의 np Pointer에 student 구조체 만큼의 Memory영역을 할당하고 해당 Memory의 주소값을 전달하고 있습니다.

이렇게 되면 이전에 할당된 구조체의 np Pointer는 이후에 할당된 구조체의 시작주소를 가지게 됨으로서 연결 List를 이루게 됩니다.


이제 이전 구조체의 Pointer에서 다음 구조체의 Pointer를 통하여 해당 구조체의 Member에 접근해서 이름과 주소를 할당합니다.

strcpy(p->np->name, "choi");
p->np->kuk = 90;
p->np->eng = 100;

그리고 마지막으로 할당된 Memory영역이 더이상 필요가 없어지면 그 Memory영역을 해제하여 그 만큼의 영역을 다시 회수해야 합니다.

free(p);
free(p->np);

free함수를 호출하여 해당 Pointer에 위치한 Memory영역을 해제합니다.

이 작업이 이루어 지지 않으면 쓸데없는 Memory공간을 낭비하게 됩니다.


2. calloc()

calloc() 함수를 이용하면 같은 Data형의 Memory공간을 여러개 배열 형태로 할당할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
  int i;
 
  p = (char *)calloc(5, 1);
 
  for (i = 0; i < 5; i++)
    printf("%d\n", p[i]);
}


calloc(5, 1)을 통해 1Byte의 Memory를 5개(0~4)의 배열로 확보하고 해당 Memory시작 주소를 Pointer p에 반환하도록 합니다.

그리고 p[배열인자]형식을 통해 각 배열의 값을 for문으로 돌면서 확인하고 있는데 그 결과는 다음과 같습니다.


참고:
calloc()함수는 Memory를 배열로 확보한고 각 배열의 초기값으로 0을 부여합니다.

이제 확보된 배열의 초기값을 직접 부여하여 그 결과를 확인해 보도록 하겠습니다.

#include <stdio.h>
#include <stdlib.h>

main()
{
  char *p;
  int i;
  char cal;
 
  p = (char *)calloc(5, 1);
 
  cal = 'a';
 
  for (i = 0; i < 5; i++)
    p[i] = cal + i;
   
  for (i = 0; i < 5; i++)
    printf("%c\n", p[i]);
  free(p);
}


확보된 각 배열 cal변수에 문자 'a'를 설정하고 for문을 통해 0부터 4까지 문자 'a'에 값을 1씩 더하여(그럼 'b'.. 'c'형태로 변할 것입니다.) 저장한 후 다시 for문을 통해 값을 확인하고 있습니다.


3. free

calloc()함수사용시에도 예외없이 free()함수를 호출하여 사용된 Memory영역을 해제해야 합니다.

사실 malloc()함수나 calloc()함수 사용시에만 free()함수를 쓸 수 있는건 아니고 필요하다면 다른 상황에도 호출하여 사용할 수 있습니다.
0 0
1
블로그 이미지

클리엘