code

증분 피연산자로 l 값이 필요

starcafe 2023. 10. 20. 13:54
반응형

증분 피연산자로 l 값이 필요

gcc 4.4.4

내가 뭘 잘못하고 있는 거지?

char x[10];
char y[] = "Hello";
while(y != NULL)
    *x++ = *y++;

어떤 조언이든 감사드립니다.

x++의 짧은 형태입니다.x = x + 1.하지만,x여기 배열이 있고 배열의 주소를 수정할 수 없습니다.당신 변수의 경우도 마찬가지입니다.y너무.

배열을 증가시키는 대신 정수를 선언할 수 있습니다.i그리고 그 다음에 접근하는 증가를 합니다.i배열의 제 인덱스입니다.

char x[10], y[5] = "Hello";
int i = 0;
while (y[i] != 0)
{
    x[i] = *y[i];
    i++;
}
x[i] = 0;

"어레이는 포인터"라는 일반적인 오해에 빠졌을 가능성이 높습니다. 즉, 배열을 정의할 때 실제로 얻는 것이 어딘가에 할당된 메모리 블록을 가리키는 일반적인 포인터입니다.코드에서 해당 포인터를 증가시키려고 시도하고 있습니다.

실제로 배열은 포인터가 아니기 때문에 코드가 "작동"하지 않습니다.배열은 배열입니다.배열을 증분할 수 없습니다.C 언어로 "배열 증가"와 같은 연산은 없습니다.사실 C에 있는 배열 자체는 수정할 수 없는 l 값입니다.C에는 배열 자체를 수정할 수 있는 작업이 없습니다(개별 요소만 수정 가능).

실제로 시도하는 "슬라이딩 포인터" 기법을 사용하여 배열을 횡단하려면 포인터를 명시적으로 생성하고 배열의 시작 요소를 가리키도록 해야 합니다.

char *px = x;
char *py = y;

그런 다음 원하는 만큼 이 포인터를 증가시킬 수 있습니다.

C의 배열은 사실 포인터이지만, 상수 포인터이므로 선언 후에는 값을 변경할 수 없습니다.

int arr[] = {1, 2, 3};
// arr is declared as const pointer.

(arr + 1)가능합니다만arr++가능하지 않습니다. 왜냐하면arr주소가 일정하기 때문에 다른 주소를 저장할 수 없습니다.

char x[10];
char y[] = "Hello";
char *p_x = &x[0];
char *p_y = &y[0];
while(*p_y != '\0') *p_x++ = *p_y++;

배열 주소를 수정할 수 없으므로 다음과 같이 수행합니다.x++그리고.y++당신의 코드에서) 그리고 당신은 포인터 주소를 수정할 수 있습니다. 저는 배열의 주소를 개별 포인터로 복사한 다음 증가시켰습니다.

원하신다면 표기를 줄일 수 있으실 거라고 확신하지만, 요점을 이해하셨으면 좋겠습니다.

x그리고.y포인터가 아닌 배열입니다.

증분식과 같은 대부분의 식 컨텍스트에서 포인터로 붕괴되지만 l 값이 아닌 r 값으로 붕괴되며 증분 연산자를 l 값에만 적용할 수 있습니다.

대개 포인터처럼 배열합니다.

배열을 수정할 수 없다는 것만 기억하세요!

그리고.y++이다.y = y + 1.

char y[] = "Hello";

그래서 당신은 배열을 수정합니다.y++!!

그것은 생산할 것입니다.error: lvalue required as increment operand.

당신이 둘 다 정의했으니깐x그리고.y배열로 수정할 수 없습니다.한 가지 가능성은 포인터를 대신 사용하는 것입니다.

char x[10];
char *xx = x;

char *y = "Hello";

while (*y != '\0')
    *xx++ = *y++;

사용자의 종료 조건도 수정했습니다. 포인터가NULL끈의 끝에 닿았다고 해서요

배열 이름을 수정할 수는 없지만 다음은?argv++인에f(int argv[])?

p99의 K&R에서 인용한 "배열 이름은 변수가 아닙니다. 구조는 다음과 같습니다.a = pa그리고.a++배열의 이름이 초기 요소의 위치에 대한 동의어임을 나타내는 "religal".

그러나 함수 매개 변수에서 왜func(char *argv[]), 할 수 있습니다argv++에도 불구하고argv는 배열 이름입니다.

그리고 인.int *a[10], 우리는 할 수 없습니다.a++맘에 들다argv++.

배열의 이름은 초기 요소의 위치와 동의어입니다. ---K&R

arrayname++불법입니다.

함수 파라미터에서와 에서 :char *argv[], 와 같습니다char **argv.type *arrayname_para[]in parameter 는 의 또다른 동의어입니다.type **arrayname_para.

배열은 할당된 메모리의 정적 연속 블록입니다.배열 이름은 첫 번째 블록 메모리에 대한 불변 참조입니다.(배열의 이름으로 참조) 주소를 증가시키려 하면 다른 메모리 위치가 손실(차등이라고 하는 것이 더 좋습니다)됩니다.준비가 되어 있다고 가정합니다.

int p[]={10,20,30}

여기서 p(설계 기준)는 인덱스 0을 나타냅니다.우리가 증가시키는 어딘가에서 다음과 같이 말합니다.p++
증분이 허용된다고 가정하면 인덱스 1을 p에서 p로 점하게 됩니다.이제 생각해보니깐p[1]=?
p[1]그러면 현재 위치의 오른쪽에 있는 한 곳의 값을 역참조하는 것으로 해석됩니다.

또는 위치p[2]원래 배열일 경우.
이 작업을 반복하면 곧 배열 인덱스를 추적하는 것이 매우 번거로울 것입니다.
따라서 이러한 사고를 방지하기 위해 배열 이름(lvalue) 주소는 불변입니다.또 다른 개념은 워드 어드레싱과 바이트 어드레싱입니다:-

C의 문자 배열( 문자열)은 단어 주소 지정 대신 바이트 주소 지정이 가능합니다.그래서 만약 우리가 배열을 가지고 있다면,

inta[]={10,20,30}

printf("%d",*(a+1)) //Ouput:20 (int is word addressable)
printf("%d",*(++a)) // Error: Array references are immutable

int* cpya=a;
printf("%d",*(++cpya)) /* Output:20 (cpy is not array reference but a copy. Hence is Mutable) */

char b[]="Hello"
printf("%c",*(++b)) // Error : Array references are immutable
printf("%c",*(b+1)) /* undefined_behavior as character Array(strings) are byte addressable and not word addressable */
printf("%c",*(b+sizeof(char)*1)) // Output :e (It's byte addressable).

To understand more I suggest reading the official docs for B 프로그래밍 언어 at
[B Reference Manual- Data Objects][1]

배열은 일정한 포인터입니다.바꿀 수 없어요.

int q;
int *const p = &q;
p = NULL; // this is not allowed.

언급URL : https://stackoverflow.com/questions/3364445/lvalue-required-as-increment-operand

반응형