How We Coding

- 출처 : http://blog.naver.com/PostView.nhn?blogId=kimsung9k&logNo=110121881497


<비트 연산을 이용한 정수의 산술연산 >


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <cstdio>
#include <vector>
using namespace std;
 
long long plus( long long a, long long b )
{
    long long xor1 = a^b;
    long long and1 = a&b;
    and1 = and1 << 1;
    while( ( and1&xor1 ) != 0 )
    {
        long long txor = and1^xor1;
        long long tand = and1&xor1;
        long long uand = tand << 1;
        and1 = uand;
        xor1 = txor;
    }
    return xor1^and1;
}
 
long long minus( long long a, long long b )
{
    long long first = a^b;
    long long second = a^(a|b);
    first = first^second;
    return plus( first, plus( (~second), 1 ) );
}
 
long long mult( long long a, long long b )
{
    bool a_is_minus = false;
    bool b_is_minus = false;
    bool is_odd = false;
 
    if( a < 0 ){
        a_is_minus = true;
        a = ~minus( a,1 );
    }
    if( b < 0 ){
        b_is_minus = true;
        b = ~minus( b,1 );
    }
    if( (b&1== 1 )
        is_odd = true;
    long long mult_a = 0LL;
    forint i=1; i < 32; i=plus( i,1 ) ){
        b = b >> 1;
        if( (b & 1== 1 )
            mult_a = plus( mult_a, (a << i) );
    }
    if( is_odd )
        mult_a = plus( mult_a, a );
    if( a_is_minus^b_is_minus )
        mult_a = plus( ~mult_a, 1 );
    return mult_a;
}
 
int main()
{
    int a, b;
    scanf("%d%d"&a, &b);
    printf("%lld\n", mult(a, b));
    return 0;
}
 
 
cs


>> 매개변수와 리턴타입을 모두 long long 으로 변경하고, 46라인을 i < 32 로 변경하니, long long 까지 처리가 가능하였다.

>> a = 100000000, b = 100000000 을 입력으로 주면 10000000000000000 이 출력된다. 

- 공백을 포함한 문자열 입력받기 


scanf("%[^\n]\n", s);


- 문자열 입력 조건을 통하여 처리하는 방법으로 문자열 조건은 [] 를 통하여 넣을 수 있다.

- ^ 는 제외를 의미. 즉 \n를 제외한 문자열을 입력받고 문자열의 끝은 \n 로 처리하는 문자열이란 뜻이 된다.



- 문자열 조건 관련 몇몇 예제


1)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[12345]s", str);
    printf("%s\n", str);
    return 0;
}
cs

>> 4567 을 입력하면 45가 출력된다.


2)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[^12345]s", str);
    printf("%s\n", str);
    return 0;
}
cs

>> 6745 를 입력하면 67이 출력된다.

>> ^ 는 []안의 문제를 제외한 나머지 문자만 인식한다.


3) 

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[0-9]s", str);
    printf("%s\n", str);
    return 0;
}
cs


>> 0-9 는 0123456789 를의미한다.

>> 123ab 를 입력하면 123이 출력된다.

>> 1a2b3c 를 입력하면 1만 출력된다.

>> ab123 을 입력하면 이상한 결과가 나온다...


4)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[a-zA-Z]s", str);
    printf("%s\n", str);
    return 0;
}
cs


>> 영문자만 입력을 받는다.



줄바꿈을 입력받지 않기 때문에, 편리한 방법이지만, 각 줄의 앞 뒤에 있는 공백은 무시하고 입력을 받아들이게 된다.

- 따라서 빈 줄은 입력받을 수 없다.

- 또한, 공백으로 시작하는 경우, 공백을 무시하고 문자부터 입력받게 된다.



참고1 : 백준 슬라이드


참고2 : http://blog.daum.net/_blog/BlogTypeView.do?blogid=09ehJ&articleno=18230445&categoryId=789155

- 실수형 값을 출력할 때, printf() 함수에서 서식문자를 %lf 혹은 %f 로 준다고 배었고, 

   기본적으로 소숫점 아래 6자리로 알고 있다. 소수점을 조정하려면 10 번 라인처럼 해야하는데,

   %g 라는 서식문자를 사용하면 그럴 필요가 없다...!!!!



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int main()
{
    double f=3.14;
 
    printf("%lf\n", f);
    // 3.140000
   
    printf("%.2lf\n", f);
    // 3.14
 
    printf("%g\n", f);
    // 3.14
 
    return 0;
}
cs


< 예제코드 >


- 7라인에서 n 에 20을 대입한다면...?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
   int i, n;
   scanf("%d"&n);
   int *arr;
   arr = (int *)malloc(sizeof(int* n);
 
   printf("%d\n"sizeof(arr));
   arr[1= 1;
   arr[198= 2;
   printf("(%d, %d)\n", arr[1], arr[198]);
 
   for(i=0; i<200; i++)
       printf("%d: %d\n", i, arr[i]);
 
   free(arr);
 
   return 0;
}
cs


>> 7 라인에서 n에 20을 입력한다.

>> 하지만 놀랍게도(?) 14 라인의 실행결과는 (1, 2) 이다. segmentation fault 가 안뜬다.

>> 그래서 16-17의 실행결과를 확인해보니.. 값을 할당하지 않은 곳은 0으로 초기화가 되어 있고, 인덱스가 1인 곳에는 1, 인덱스가 198인 곳에는 2가 저장되어있다.

     그래서 검색을 해봤다.


- 배열의 크기를 넘어서 사용하게 되면...

>> 아래 블로그에서 원하는 답변을 얻을 수 있었다.


http://blog.naver.com/PostView.nhn?blogId=tipsware&logNo=221054714926



>> 결론만 몇가지 말하면, 문법상 오류는 아니며, 예외처리는 개발자가 알아서 해야한다고 한다.

>> 또한, 이렇게 코딩을 해도 문제가 없다고 넘어가면, 돌아오는 것은 버그 라고 한다..



- 이 의문은 같이 스터디를 하는 동생의 질문에서 시작되었다.

- 블로그에서 관련내용을 다시 잘 정리한 것 같다.


- http://www.crocus.co.kr/1171?category=278489