방금 C를 공부하기 시작했고 포인터를 함수의 매개 변수로 포인터에 전달하는 예제를 수행 할 때 문제를 발견했습니다.
이것은 내 샘플 코드입니다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int* allocateIntArray(int* ptr, int size){
if (ptr != NULL){
for (int i = 0; i < size; i++){
ptr[i] = i;
}
}
return ptr;
}
void increasePointer(int** ptr){
if (ptr != NULL){
*ptr += 1; /* <----------------------------- This is line 16 */
}
}
int main()
{
int* p1 = (int*)malloc(sizeof(int)* 10);
allocateIntArray(p1, 10);
for (int i = 0; i < 10; i++){
printf("%d\n", p1[i]);
}
increasePointer(&p1);
printf("%d\n", *p1);
p1--;
free(p1);
fgets(string, sizeof(string), stdin);
return 0;
}
16 행 *ptr+=1
에서 *ptr++
. 예상되는 결과는 전체 배열과 숫자 1이어야하지만 내가 사용할 *ptr++
때 결과는 0입니다.
+=1
과 사이에 차이 가 ++
있습니까? 둘 다 똑같다고 생각했습니다.
답변
차이점은 연산자 우선 순위 때문입니다.
사후 증가 연산자 ++
는 역 참조 연산자보다 우선 순위가 높습니다 *
. 그래서 *ptr++
동일합니다 *(ptr++)
. 즉, 포스트 증가는 포인터가 가리키는 것이 아니라 포인터를 수정합니다.
할당 연산자는 +=
참조 연산자보다 낮은 우선 순위를 가지고 *
있으므로, *ptr+=1
동일하다 (*ptr)+=1
. 즉, 할당 연산자는 포인터가 가리키는 값을 수정하고 포인터 자체는 변경하지 않습니다.
답변
질문에 관련된 세 연산자의 우선 순위는 다음과 같습니다.
사후 증가 ++
> 역 참조 *
> 할당+=
주제에 대한 자세한 내용은 이 페이지 에서 확인할 수 있습니다 .
표현식을 구문 분석 할 때 일부 행에 나열된 연산자는 그 아래 행에 나열된 연산자보다 인수에 더 밀접하게 바인딩됩니다 (괄호로 묶인 것처럼). 예를 들어 표현식
*p++
은로가*(p++)
아니라로 구문 분석 됩니다(*p)++
.
간단히 말해서, *ptr+=1
post-increment 연산자를 사용 하여이 할당을 표현 하려면 역 참조 연산자에 괄호를 추가 ++
하여이 작업보다 우선 순위를 부여해야합니다.(*ptr)++
답변
작업 순서 를 표시하기 위해 괄호를 적용 해 보겠습니다.
a + b / c
a + (b/c)
다시 해보자
*ptr += 1
(*ptr) += 1
그리고 다시
*ptr++
*(ptr++)
- 에서는
*ptr += 1
포인터가 가리키는 변수의 값을 증가시킵니다 . - 에서
*ptr++
, 우리는 포인터를 증가 후에 이루어집니다 우리의 전체 문 (코드 행) 및 변수에 우리의 포인터에 대한 참조를 반환 포인트 에.
후자는 다음과 같은 작업을 수행 할 수 있습니다.
for(int i = 0; i < length; i++)
{
// Copy value from *src and store it in *dest
*dest++ = *src++;
// Keep in mind that the above is equivalent to
*(dest++) = *(src++);
}
이것은 src
배열을 다른 dest
배열 로 복사하는 데 사용되는 일반적인 방법 입니다.
답변
아주 좋은 질문입니다.
K & R “C 프로그래밍 언어” “5.1 포인터 및 주소”에서 이에 대한 답을 얻을 수 있습니다.
“단항 연산자 * 및 &는 산술 연산자보다 더 밀접하게 결합합니다.”
*ptr += 1 //Increment what ptr points to.
“* 및 ++와 같은 단항 연산자는 오른쪽에서 왼쪽으로 연결 됩니다.”
*ptr++ //Increment prt instead of what ptr point to.
// * (ptr ++)처럼 작동합니다.
올바른 방법은 다음과 같습니다.
(*ptr)++ //This will work.
답변
* ptr + = 1 : ptr이 가리키는 데이터를 증가시킵니다. * ptr ++ : 포인터가 가리키는 데이터 대신 다음 메모리 위치를 가리키는 포인터를 증가시킵니다.