어레이 이름이 포인터입니까?
어레이 이름이 C의 포인터입니까?그렇지 않은 경우 어레이 이름과 포인터 변수의 차이점은 무엇입니까?
배열은 배열이고 포인터는 포인터이지만 대부분의 경우 배열 이름은 포인터로 변환됩니다.자주 사용되는 용어는 포인터로 쇠퇴한다는 것입니다.
어레이는 다음과 같습니다.
int a[7];
a
에는 7개의 정수를 위한 공간이 포함되어 있으며 이들 중 하나에 다음과 같이 할당과 함께 값을 입력할 수 있습니다.
a[3] = 9;
다음은 포인터입니다.
int *p;
p
에는 정수의 공백이 포함되어 있지 않지만 정수의 공백을 가리킬 수 있습니다.의 한 수 .a
「 」 「 」 、 「 。
p = &a[0];
혼란스러울 수 있는 것은, 다음과 같은 것도 쓸 수 있다는 것입니다.
p = a;
어레이의 내용은 복사되지 않습니다.a
p
」 ) 에, 「 」를 사용합니다.a
첫 번째 요소에 대한 포인터로 변환됩니다.그러면 이 과제는 이전 과제와 동일하게 수행됩니다.
, 그럼 에는 '어울릴 수 .p
어레이와 유사한 방법으로 다음을 수행합니다.
p[3] = 17;
C의 C가 동작하기 입니다.[ ]
는 포인터의 관점에서 정의됩니다. x[y]
: 포인터부터 합니다.x
, 디세이블화y
포인터가 가리키는 것 다음에 요소를 전진시키고, 거기에 있는 모든 요소를 취합니다.구문을 하여 " " " 를 합니다.x[y]
쓸 수 *(x+y)
.
을 통상의 「 」등로 동작시키려면 , 다음의 순서에 따릅니다.a
, " " " "a
a[3]
(먼저 로 변환해야 합니다.a
그런 다음 3가지 요소를 전진시키고 거기에 있는 모든 요소를 취합니다.which, 배 에 3 、 에 3 에 which 에 ( 03 in첫첫 、 0 0 、 첫 0 、 첫 0 、 첫으 、 element으으 으으 in in 。
요약하면, C 프로그램의 배열 이름은 (대부분의 경우) 포인터로 변환됩니다. 가지 는 ''를 할 때 입니다.sizeof
어레이의 연산자. ifa
되었습니다.sizeof a
는 실제이 포인터의 크기를 알 수 없기 때문에 이 경우 포인터는 필요 .a
배열 자체를 의미합니다.
배열이 값으로 사용되는 경우 배열의 이름은 첫 번째 요소의 주소를 나타냅니다.
배열을 값으로 사용하지 않을 경우 배열 이름이 전체 배열을 나타냅니다.
int arr[7];
/* arr used as value */
foo(arr);
int x = *(arr + 1); /* same as arr[1] */
/* arr not used as value */
size_t bytes = sizeof arr;
void *q = &arr; /* void pointers are compatible with pointers to any object */
타입의 식이큰도 아닌 .&
★★★★★★★★★★★★★★★★★」sizeof
「N-element array of T」는 「T」의 「N-element array of T」의 「T에 포인터」입니다.식 값은 배열 내 첫 번째 요소의 주소입니다.
즉, 어레이 이름은 포인터가 아니지만 대부분의 컨텍스트에서 포인터로 취급됩니다.
편집
코멘트의 질문에 대한 답변:
sizeof를 사용하는 경우 어레이 요소만 세나요?그러면 어레이 "head"는 길이와 포인터에 대한 정보를 포함한 공간도 차지합니다(이것은 일반 포인터보다 더 많은 공간을 차지한다는 것을 의미합니다).
어레이를 생성할 때 할당되는 공간은 요소 자체를 위한 공간뿐입니다. 개별 포인터나 메타데이터를 위한 스토리지는 구현되지 않습니다.정해진
char a[10];
기억에 남는 건
+---+
a: | | a[0]
+---+
| | a[1]
+---+
| | a[2]
+---+
...
+---+
| | a[9]
+---+
표현 a
전체 어레이를 참조하지만 개체가 없습니다. a
어레이 요소 자체에서 분리됩니다.thus따는sizeof a
는 어레이 전체의 크기(바이트 단위)를 나타냅니다..&a
는 첫 번째 요소의 주소와 동일한 배열 주소를 제공합니다.의 차이점&a
★★★★★★★★★★★★★★★★★」&a[0]
결과1 유형입니다.char (*)[10]
번째 및 첫 번째 경우char *
두 번째에.
때 입니다. 즉, 은 개별 요소에 접근하고 싶을 때 입니다.표현a[i]
됩니다.*(a + i)
값 - " 값 지정"a
, 「」i
해당 주소의 요소(바이트가 아님)를 입력하고 결과를 참조 해제합니다.
는 제는 the the the the the the the the thea
포인터나 주소가 아니라 어레이 객체 전체입니다.예: "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C")a
형, 형, 형, 형, 형, 형, 형, 형, 형, 형, 형, 형, 형.char [10]
이 표현은 피연산자의 피연산자가 아닙니다.sizeof
단항식&
유형됩니다.char *
식 값은 배열의 첫 번째 요소의 주소입니다.따라서 이 표현은 a
및 있습니다.&a[0]
로는 (식)이행자」)*a
및 있습니다.a[0]
B라는 했으며, B C C C B b B 는 B b b B b b b b b B b b b 에 c B c B c 。a
어레이 요소에서 분리된 포인터 개체입니다.a[0]
,a[1]
Ritchie는 B의 배열 시멘틱스를 유지하고 싶었지만 별도의 포인터 오브젝트를 저장하는 것을 방해하고 싶지 않았습니다.이치노대신 컴파일러는 필요에 따라 변환 중에 어레이 식을 포인터 식으로 변환합니다.
어레이는 그 크기에 관한 메타데이터를 저장하지 않습니다.배열 식이 포인터로 "감소"되는 즉시 단일 요소에 대한 포인터만 표시됩니다.이 요소는 일련의 요소 중 첫 번째 요소일 수도 있고 단일 개체일 수도 있습니다.포인터만으로는 알 수 없습니다.
포인터는 첫요소에 입니다. 의 크기를 알 수 이에 "배열식"은 " 크기를 알 수 없습니다.이 함수는 배열의 크기를 인식하지 않습니다(이 때문에gets
이 기능은 매우 위협적이어서 결국 라이브러리에서 제거되었습니다.)함수가 배열에 포함된 요소의 수를 확인하려면 sentinel 값(C 문자열의 0 끝자 등)을 사용하거나 요소 수를 별도의 매개 변수로 전달해야 합니다.
- 어떤 *주소 값이 해석되는 방법에 영향을 미칠 수 있습니다.기계에 따라 다릅니다.
다음 예시는 배열 이름과 포인터의 구체적인 차이를 보여 줍니다.주어진 최대 치수로 1D 선을 표현하려면 배열 또는 포인터를 사용할 수 있습니다.
typedef struct {
int length;
int line_as_array[1000];
int* line_as_pointer;
} Line;
이제 다음 코드의 동작을 살펴보겠습니다.
void do_something_with_line(Line line) {
line.line_as_pointer[0] = 0;
line.line_as_array[0] = 0;
}
void main() {
Line my_line;
my_line.length = 20;
my_line.line_as_pointer = (int*) calloc(my_line.length, sizeof(int));
my_line.line_as_pointer[0] = 10;
my_line.line_as_array[0] = 10;
do_something_with_line(my_line);
printf("%d %d\n", my_line.line_as_pointer[0], my_line.line_as_array[0]);
};
이 코드는 다음과 같이 출력됩니다.
0 10
는 함수 에서 에 대한 호출이 입니다.do_something_with_line
오브젝트는 다음과 같이 복사되었습니다.
- " "
line_as_pointer
에는, 하고 있던 되어 있습니다. - " " "
line_as_array
않는 되었습니다.
따라서 어레이를 함수에 직접 입력할 때 어레이는 값에 의해 주어지지 않지만 구조체에 캡슐화하면 값(복사됨)에 의해 주어집니다.이것은 포인터를 사용한 구현과 비교하여 동작의 큰 차이를 나타내고 있습니다.
이 예에서는, 이 문제를 명확하게 하고 있다고 생각합니다.
#include <stdio.h>
int main()
{
int a[3] = {9, 10, 11};
int **b = &a;
printf("a == &a: %d\n", a == b);
return 0;
}
gcc 4.9.2에서 (2개의 경고 포함)를 컴파일하여 다음 내용을 출력합니다.
a == &a: 1
웁스:-)
결론적으로 어레이는 포인터가 아닙니다.& operator를 사용하면 주소를 얻을 수 있기 때문에, 어레이는 포인터로서 메모리에 격납되지 않습니다(읽기 전용도 아닙니다).그러나 - ohs - 해당 연산자는 작동하지 않습니다:-) 어느 쪽이든 경고를 받았습니다.
p.c: In function ‘main’:
pp.c:6:12: warning: initialization from incompatible pointer type
int **b = &a;
^
p.c:8:28: warning: comparison of distinct pointer types lacks a cast
printf("a == &a: %d\n", a == b);
C++는 컴파일 시 오류가 발생하여 이러한 시도를 거부합니다.
편집:
제가 보여드리고 싶은 것은 다음과 같습니다.
#include <stdio.h>
int main()
{
int a[3] = {9, 10, 11};
void *c = a;
void *b = &a;
void *d = &c;
printf("a == &a: %d\n", a == b);
printf("c == &c: %d\n", c == d);
return 0;
}
그럼에도 불구하고.c
★★★★★★★★★★★★★★★★★」a
같은 , 「포인트」라고 하는 를 얻을 수 c
할 수 .a
포인터
이렇게 선언된 배열
int a[10];
는, 10 월 월에 대해서 메모리를 합니다.int
스는 수정할 수 .a
는 할 수 요.a
.
와 같은 합니다.p
:
int *p;
은 전혀되지 않습니다.int
할 수 . 변경할 수 있습니다.
p = a;
어레이 서브스크립트를 사용합니다.
p[2] = 5;
a[2] = 5; // same
*(p+2) = 5; // same effect
*(a+2) = 5; // same effect
어레이 이름 자체에서 메모리 위치가 생성되므로 어레이 이름을 포인터처럼 취급할 수 있습니다.
int a[7];
a[0] = 1976;
a[1] = 1984;
printf("memory location of a: %p", a);
printf("value at memory location %p is %d", a, *a);
또, 포인터(오프셋의 추가/축소등)에 대해서 할 수 있는 그 외의 중요한 작업도, 어레이에 대해서 실시할 수 있습니다.
printf("value at memory location %p is %d", a + 1, *(a + 1));
언어면에서는 C가 어레이를 단순히 포인터(pointer)로 표시하지 않은 경우(병리학적으로는 메모리 위치일 뿐입니다).메모리내의 임의의 장소를 가리킬 수도, 프로그래머에 의해서도 제어할 수도 없습니다).항상 코드화할 필요가 있습니다.
printf("value at memory location %p is %d", &a[1], a[1]);
어레이 이름은 포인터처럼 동작하며 어레이의 첫 번째 요소를 가리킵니다.예:
int a[]={1,2,3};
printf("%p\n",a); //result is similar to 0x7fff6fe40bc0
printf("%p\n",&a[0]); //result is similar to 0x7fff6fe40bc0
두 인쇄문 모두 기계에 대해 정확히 동일한 출력을 제공합니다.내 시스템에서는 다음을 제공합니다.
0x7fff6fe40bc0
어레이 이름은 어레이의 첫 번째 요소의 주소입니다.따라서 yes 어레이 이름은 const 포인터입니다.
언급URL : https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer
'programing' 카테고리의 다른 글
vue.js 템플릿 구성 요소를 사용하기 위해 v-에서 생성한 목록 항목에 클릭 시 클래스를 바인딩하려면 어떻게 해야 합니까? (0) | 2022.08.24 |
---|---|
비밀번호로 String보다 char[]가 선호되는 이유는 무엇입니까? (0) | 2022.08.24 |
Java에서 2 * (i * i)가 2 * i * i보다 빠른 이유는 무엇입니까? (0) | 2022.08.21 |
vue2-dataerange-picker 드롭다운에서 연도 선택 (0) | 2022.08.21 |
Kotlin과 Java의 String은 무엇입니까? (0) | 2022.08.21 |