마지막 문장이 어떻게 포인터를 증가시키는 지 이해할 수 없습니다. 몇 가지 예를 들어 설명해 주시겠습니까? 도시 된 바와 같이대체 방법을 사용한 순환 버퍼 증가
답변
코드 :
aptr = (aptr + 1) & (void *)(BUFFERSIZE - 1);
// |________| incremented here
는 원형 버퍼는 버퍼의 크기가 2의 거듭 제곱은 다음 &
간단히 마스킹 롤오버하는 쉽고 빠른 방법 때문이다. 그런 다음, BUFFERSIZE
이 256
이라고 가정하면 : 선택
num & (257 - 1) != num % 257
num & (0x101 - 1) != num % 0x101
num & 0x100 != num % 0x101
(void *)
허용 컴파일러 :
num & (256 - 1) == num % 256
num & (0x100 - 1) == num % 0x100
num & (0x0ff) == num % 0x100
수는 2의 거듭 제곱 아닙니다
, 당신은 마스킹 기술을 사용할 수 없습니다 포인터 너비에 따라BUFFERSIZE
상수의 적절한 너비 ... 일반적으로 알고있는 것이 가장 좋습니다 -! - 다음과 같은 명령문 앞에 오는 너비.
&
이 에뮬레이트 된 롤오버 이벤트를 발생시키는 이유를 분명히하기 위해 16 진법을 추가했습니다. 0xff
은 이진수 인 0x11111111
이므로 AND 연산은 단순히 상위 비트를 마스킹하는 것입니다.
제 의심은 num이 ANDED (void *) (BUFFERSIZE-1)입니다. 실제로 포인터 타입으로 num을 덧붙이면 일반 정수가 아닌 num을 직접 (256-1) 사용할 수 있습니다. 내 가정은, 그것이 num & & nbsp; (BUFFERSIZE-1) 였으면, 당신이 말하는 최종 답을 얻었을 것입니다. –
'aptr '은 어떤 종류의 포인터, 즉'uint16_t * aptr'로 선언되었을 것입니다.이 경우에는 유효합니다. – slightlynybbled
포인터 값을 bitwise에 전달하면 [제약 조건 위반] (http://port70.net/~nsz/c/c11/n1570.html#6.5.10p2)이므로 진단이 생성되어야합니다. –
2이 방법의 문제점.
가) 비트 단위 연산과 함께 포인터를 사용하는 것은 이식성이없는 코드입니다. char
및 BUFFERSIZE
보다 넓은 개체에 aptr
점은 버퍼의 원소의 개수 인 경우 char *
와 유사한 void *
의 비표준 연산을 지원 컴파일러 @Ilja Everilä
char *aptr;
// error: invalid operands to binary & (have 'char *' and 'void *')
// The following increments the index: (not really)
// aptr = (aptr + 1) & (void *)(BUFFERSIZE-1);
B)는 수학 잘못 바이트 크기가 아닙니다. 물론 비표준 컴파일러가 some_type * & void *
을 구현하는 방법에 따라 다릅니다. 일부 구현 특정 동작을 사용하기 위해 불필요하게 코딩하는 것은 왜 까닭입니까?
대신 i % BUFFERSIZE
을 사용하십시오. 이 휴대용 접근 방식은 BUFFERSIZE
이 2의 거듭 제곱이고 잘되지 않을 때 작동합니다. 컴파일러가 i % power-of-2
및 i
이 부호없는 유형 인 경우에는 동일한 코드가 확실히 i & (power-of-2 - 1)
으로 생성됩니다.
이 최적화를 인식하지 못하는 컴파일러의 경우 더 나은 컴파일러를 고려해야합니다.
#define BUFFERSIZE 256
int main(void) {
char buf[BUFFERSIZE];
// pointer solution
char *aptr = buf;
aptr = &buf[(aptr - buf + 1) % BUFFERSIZE];
// index solution
size_t index = 0;
index = (index + 1) % BUFFERSIZE;
}
- 1. 가변 크기 항목을 사용한 순환 버퍼 구현
- 2. 순환 버퍼 파이썬 구현
- 3. 순환 버퍼 구현
- 4. 스칼라 컬렉션 순환 버퍼
- 5. 역 순환 버퍼
- 6. 디스크의 순환 버퍼 구현
- 7. VB.NET의 순환 버퍼
- 8. 플래시의 순환 버퍼
- 9. 순환 FIFO 버퍼 사용
- 10. 순환 버퍼 구문 분석
- 11. 순환 버퍼 최적화
- 12. 하드웨어의 순환 (순환 또는 순환) 버퍼 : 마이크로 프로세서에서 사용 가능한가?
- 13. 순환 버퍼 시도 - 자바 스크립트
- 14. C++ 단순 순환 버퍼 큐
- 15. C 순환 버퍼 효율 향상
- 16. 순환 버퍼 비교/검색 알고리즘
- 17. C++ : 순환 버퍼 관련 문제
- 18. Oclint를 사용한 Npath와 순환 복잡성
- 19. Concat 버퍼 또는 대체 방법
- 20. setter를 사용한 스프링 순환 의존성
- 21. emacs : 제어 탭 버퍼 순환 또는 스택 버퍼 순환, windows 사이의 alt-tab과 유사
- 22. join을 사용한 대체 구문
- 23. missForest를 사용한 부분 대체
- 24. 링 버퍼/순환 큐의 실제 예는 무엇입니까?
- 25. 부스트 순환 버퍼 포인터 액세스 (C++)
- 26. 순환 버퍼 오디오 녹음 iOS : 가능합니까?
- 27. 이 순환 버퍼 구현에는 세마포어가 필요합니까?
- 28. 모듈로 연산을 사용하지 않는 순환 버퍼
- 29. C 테스트 문제에서 순환 버퍼 구현
- 30. deque를 사용하여 C++에서 순환 버퍼 구현
이것은 정말 나쁜 코드입니다. –
2의 강점 때문에 비트 맵 (BUFFERSIZE-1)을 사용하여 오버플로되었을 때 인덱스를 0으로 롤백 할 수 있습니다. 코드 작성자는 모듈러스 연산자 또는 조건 분기를 사용하여 성능이 저하되는 것을 피하려고합니다. –
그는 [BUFFERSIZE-1] (AND *) 대신 [BUFFERSIZE-1]과 직접 AND should하지 않아야합니까? –