2016-09-17 3 views
-2
#include <stdio.h> 

void set_flag(int* flag_holder, int flag_position){ 
*flag_holder |= (1 << flag_position); 
} 

void set_flag(int* flag_holder, int flag_position); 

int main(int argc, char* argv[]) 
{ 
int flag_holder = 0; 
int i; 

set_flag(&flag_holder, 3); 
set_flag(&flag_holder, 16); 
set_flag(&flag_holder, 31); 

다음 내용은 혼란 스럽습니다. 포인터가 void set_flag() 내에 있다고 생각하는데, 그 값을 3, 16, 31로 설정하면 확실하지 않다는 것을 알았습니까? &포인터가있는 함수를 C로 이해하려고 시도했습니다.

set_flag(&flag_holder, 3); 
set_flag(&flag_holder, 16); 
set_flag(&flag_holder, 31); 
+3

'| '는 비트 OR 연산자입니다. 먼저 비트 연산자에 대해 읽어야합니다. – Raman

+1

이것은 함수에 관한 것이 아니라 단지'flag_holder | = (1 << 3);/* ... * /'는 동등한 것일 것입니다 – Veltas

+0

'flag_position'은 설정하려는 *** 비트 ***입니다. 귀하의 예를 들어, '0..31' 범위. 먼저 'flag_holder'의 비트 3을 설정 한 다음 비트 16을 설정하고 마지막으로 31을 설정합니다. –

답변

0

그것이 적용되는 변수의 주소를 가져오고 * 포인터에 의해 제공되는 주소에있는 값을 얻는다.

함수 선언에서 int *은 인수가 포인터 인 정수로 선언합니다. 그런 다음 함수 내에서 값이 수정되고 주어진 주소에 다시 쓰여집니다.

flag_holder의 주소를 main에 전달하면이 주소의 값이 set_flag(...)에서 수정됩니다.

0

발신자가 정수의 주소를 전달 중입니다. 호출 수신자는 전달 된 주소를 역 참조하여 해당 정수에 새 값을 할당합니다. 값 대신에 주소가 직접 전달되는 이유는 서브 루틴이 정수를 수정할 수 있기 때문입니다.

새로운 값은 전달되는 값에 따라 개별 값을 반전하는 이전 값을 기반으로합니다. 그러나 이것은 정말로 귀하의 게시물의 제목과는 별도의 질문입니다. 그런 다음 데이터에 대한 몇 가지 비트 OR 연산을 수행하는 int

  • 정수 값
  • 에 대한 포인터 -

    • int* :

    0

    기능 set_flag 2 인자 소요됩니다.

    따라서 예에서는 이 첫 번째 값으로, 3, 16 및 31이 두 번째 값으로 사용됩니다. 이것은 (32bit INT 가정) 결과 :

    flag_holder = 00000000 00000000 00000000 00000000 = 0 in binary 
    (1 << 3) = 00000000 00000000 00000000 00001000 = 1 left shifted by 3 
    OR result = 00000000 00000000 00000000 00001000 = result of | binary operation 
    

    또 다른 예를 들어 당신이 flag_holder에 대한 다른 값했을 경우 :

    set_flag() 기능 flag_holder의 값을 조작 할 비트 연산자를 사용
    flag_holder = 00000000 00010000 00001000 10000001 
    (1 << 3) = 00000000 00000000 00000000 00001000 
    OR result = 00000000 00010000 00001000 10001001 
    
    +0

    감사합니다. 제 3의 예에서는 31 점 이동하기 때문에 32 비트는 OP에 더 그럴듯하다고 생각합니다. – HectorLector

    0

    의 비트에서을 수평.

    비트 OR | 연산자를 사용하여 개별 비트를 설정할 수 있습니다. 플래그를 설정하는 데 사용되는 유사한 기술은 다음과 같습니다

    #define flag1 0x01 
    #define flag2 0x02 
    #define flag3 0x04 
    #define flag4 0x08 
    #define flag5 0x10 
    ... you get the idea. 
    

    우리는 다음 각각의 비트를 설정하기 위해 OR 연산자를 사용할 수 있습니다

    이진의 관점에서 플래그의 값을 생각하면
    char flags = 0; 
    
    flags |= flag1 
    

    - 상상해보십시오 :

    flag1 = 00000001 
    flag2 = 00000010 
    flag3 = 00000100 
    flag4 = 00001000 
    

    아이디어가 있습니다. OR 연산자는 rvalue에 설정된 비트를 lvalue로 복사하여 효과적으로 비트 또는 플래그를 설정합니다.

    그래서 flags |= (flag1 | flag3)을하고 우리의 깃발을 초래할 것 :

    flags 00000101 
    

    우리는 특정 옵션이 지정되었는지 여부를 지정하려면이 같은 것을 사용할 수 있습니다.

    귀하의 예는 다른 기술을 사용, 그것은 항상 위의 예에서이 같은 생각 ... 1 비트 이동 값이 적용되는 경우 0x01로 우리가 00000001 < < 1 시간을 이동하면 == 00000001

    우리 get 00000010.

    에 대한 포인터를 받아들이면, 두 번째 매개 변수는 1을 왼쪽으로 이동시키고 특정 비트를 분리 할 위치를 지정하는 것입니다.

    비트 연산자에 대해 읽어야합니다. 재미있을 것입니다.

    1

    비트 물건을 없애고 포인터에 집중 해 봅시다.

    void set_flag(int* flag_holder, int flag_position) { 
        *flag_holder = flag_position; 
    } 
    

    이 기능의 목적은 발신자의 변수를 변경하는 것입니다. 당신은 너무처럼 전화 :

    int *flag; 
    set_flag(&flag, 5); // flag is now 5 
    

    & 다시 그것을 가리키는 무슨에 *는 포인터를 회전, 포인터를 만든다.

    flag_holder은 정수를 가리키는 포인터이며 메모리의 정수 위치입니다. 약 32 또는 64 비트 숫자입니다. flag_position은 일반 정수입니다.

    set_flag 경우 가장 가능성이 컴퓨터가 말을 "아니, 당신은 할 수 없어, 그게 아니라 당신의 기억" "메모리 위치 (5)에 flag_holder을 지적 해주십시오"하고 프로그램을 충돌라고 말한다 flag_holder = flag_position을 시도했다.

    대신 "당신이 가리키고있는 번호를 5와 같게 변경하십시오"라고 말하면서 *flag_holder = flag_position입니다.

    관련 문제