c에서 배열 이름이 정확히 무엇입니까?
C의 배열 이름의 종류와 사용법을 이해하는 데 어려움을 겪고 있습니다.글이 길어보일지도 모르지만 참아주세요.
다음 문구는 다음과 같이 선언하는 것으로 알고 있습니다.a전형적인int []즉, 정수들의 배열.
int a[30];
하는 동안에a또한 배열의 첫번째 요소와 같은 것들을 가리킵니다.*(a+2)유효합니다.그래서 만들기는a정수를 가리키는 것처럼 보입니다.하지만 실제로 유형은int []그리고.int*는 다릅니다. 전자는 배열 유형이고 후자는 정수를 가리키는 포인터입니다.
유형의 변수이기도 합니다.int []유형의 변수로 변환됩니다.int*그것을 기능에 전달할 때; 에 있는 것처럼.C배열은 참조를 통해 전달됩니다(단, 제외).sizeof연산자).
여기에 나를 흔들리게 하는 지점이 있습니다.다음 코드를 살펴봅니다.
int main()
{
int (*p)[3];
int a[3] = { 5, 4, 6 };
p = &a;
printf("a:%d\t&a:%d\n",a,&a);
printf("%d",*(*p + 2));
}
출력:
a:2686720 &a:2686720
6
그렇다면 위의 코드는 어떻게 작동하는 것입니다.두 가지 질문이 있습니다.
a그리고.&a같은 가치관을 가지고 있습니다. 왜죠?- 정확히 무엇이
int (*p)[3];- 그래요? - 배열에 대한 포인터를 선언합니다. 저도 알고 있습니다.그러나 배열의 포인터와 배열의 첫 번째 요소 및 이름은 어떻게 다릅니까?
누가 설명해 줄 수 있습니까?저는 굉장히 많은 혼란을 겪고 있습니다.
사용해야 한다는 것을 알고 있습니다.%p사용 대신 자리 표시자로서%d포인터 변수의 값을 인쇄합니다.정수 자리 표시자를 사용하면 잘린 주소를 인쇄할 수 있습니다.하지만 저는 일을 단순하게 하고 싶습니다.
다른 답변들은 이미 그 문제에 대해 설명했습니다.나는 약간의 도표를 가지고 그것을 설명하려고 합니다.이것이 도움이 되길 바랍니다.
배열을 선언할 때
int a[3] = {5, 4, 6}
기억의 배열은 다음과 같습니다.
이제 질문에 답하겠습니다.
a그리고.&a가치관이 같습니다.어떻게?
너도 이미 알고 있듯이ais는 배열 유형 및 배열 이름입니다.a배열의 첫번째 요소에 대한 포인터가 됩니다.a(붕괴 후), 즉 주소를 가리킵니다.0x100하세요. :0x100또한 메모리 블록(array)의 시작 주소입니다.a일반적으로 첫 번째 바이트의 주소는 변수의 주소라고 합니다.즉, 변수가 100바이트이면, 변수의 주소는 첫 번째 바이트의 주소와 같습니다.
&a는 전체 메모리 블록의 주소, 즉 배열의 주소입니다.a. 다이어그램 참조:

이제 당신은 그 이유를 이해할 수 있습니다.a그리고.&a둘 다 다른 유형이지만 주소 값이 같습니다.
그게 정확히 무슨 일을 하는 거지?
int (*p)[3];배열에 대한 포인터를 선언합니다. 알고 있습니다.그런데 배열의 포인터가 배열의 첫 번째 요소와 배열의 이름에 대한 포인터와 어떻게 다릅니까?
위 그림을 참조하십시오. 배열에 대한 포인터와 배열 요소에 대한 포인터가 어떻게 다른지 명확히 설명되어 있습니다.
할당할때&a.p,그리고나서p시작 주소를 가진 전체 배열을 가리킵니다.0x100.
참고: 라인 관련
... 와 같이
C배열은 참조를 통해 전달됩니다(단, 예외).sizeof함수).
C에서 인수는 값으로 전달됩니다.C에 기준 통과가 없습니다.일반 변수가 함수에 전달되면 해당 값이 복사됩니다. 해당 매개 변수에 대한 변경 사항은 변수에 영향을 주지 않습니다.
배열은 값에 의해서도 전달되지만, 다른 점은 배열 이름이 첫 번째 요소에 대한 포인터와 함수의 매개 변수(여기서는 포인터 값이 복사됨)에 할당된 포인터로 손상된다는 것입니다. 배열 자체는 복사되지 않습니다.
일반 변수와 달리 인수로 사용되는 배열은 배열 자체의 복사본이 만들어지지 않고 첫 번째 요소에 대한 포인터 복사가 만들어지기 때문에 변경에 대해 보호되지 않습니다.
당신은 또한 주의해야 합니다.sizeof는 함수가 아니며 배열 이름은 이 경우 인수로 작동하지 않습니다.sizeof는 연산자이며 배열 이름은 피연산자 역할을 합니다.배열 이름이 단항의 피연산자인 경우에도 동일함&교환입니다.
- a 와 &a 는 같은 값을 갖습니다.어떻게?
그들은 가치는 같지만 종류는 다릅니다.배열 개체는 요소 사이(이전 또는 이후)에 패딩이 없으므로 배열의 주소와 배열의 첫 번째 요소의 주소가 동일합니다.
즉,
(void *) a == (void *) &a
- 정확히 무엇을 하는지 int(*p)[3]; 배열에 대한 포인터를 선언합니다. 알고 있습니다.그런데 배열의 포인터가 배열의 첫 번째 요소와 배열의 이름에 대한 포인터와 어떻게 다릅니까?
이 두 가지 포인터 유형이 있습니다.포인터 산술을 예로 들겠습니다.
a + 1 /* address of the second element of the array */
&a + 1 /* address one past the last element of the array */
편집: 대중적인 수요로 인해 아래에 어레이 변환에 대한 정보를 추가했습니다.
세 가지 예외를 제외하고 식에서 유형 배열의 객체는T에 대한 유형 포인터 값으로 변환됩니다.T배열의 첫 번째 요소를 가리킵니다.예외는 개체가 다음의 피연산자인 경우입니다.sizeof아니면&단항 연산자 또는 객체가 배열을 초기화하는 문자열 리터럴인 경우.
예를 들어 다음과 같은 문장이 있습니다.
printf("a:%d\t&a:%d\n", a, &a);
는 사실 다음과 같습니다.
printf("a:%d\t&a:%d\n", &a[0], &a);
참고하시기 바랍니다.d변환 지정자는 서명된 정수를 인쇄하는 데만 사용할 수 있으며, 포인터 값을 인쇄하는 데 사용해야 합니다.p지정자(그리고 인수는 다음과 같아야 합니다.void *일을 올바르게 수행하려면 다음을 사용합니다.
printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
각각:
printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
- a는 배열의 0번째 요소를 가리키는 포인터에 해당합니다.반면, &a의 경우도 마찬가지입니다.배열의 시작 주소만 알려줍니다.
~하듯이,a --> pointer pointing to starting element of array a[],it does not know about other element's location..
&a --->address location for storing array a[] which stores first element location,but knows every element's location.
마찬가지로, 다른 요소의 위치는 (a+2), (a+4) 등 배열의 끝까지입니다.
그래서 그런 결과가 나온 겁니다.
- int(*p)[3]은 배열에 대한 포인터입니다.만약 int *p[3]였다면, 전혀 다른 의미였을 것입니다.이 문맥과는 완전히 다른 포인터들의 배열을 의미했을 것입니다.
배열에 대한 포인터는 배열의 다른 모든 요소를 자동으로 처리합니다.이 경우, 당신의 것은 (p);
반면 배열의 첫 번째 요소에 대한 포인터, 즉 a는 배열의 첫 번째 요소에 대해서만 알 수 있습니다.다음 요소에 액세스하려면 포인터 산술 방향을 수동으로 지정해야 합니다.보세요. 이 경우 a에 2를 더하면 a에서 두 번째 원소, 즉 a+2를 더하면 세 번째 원소를 얻을 수 있습니다. a, 즉 a+4 등에 4를 더하면 // 정수 배열이므로 2의 차이에 유의하십시오!
질문 1에 대한 답으로, 대부분의 다른 현대 언어 C/C++는 메모리의 주소를 직접 조작할 수 있고 그것을 '이해'할 수 있는 시설을 내장한 것과 달리 이것은 단순히 설계된 C 언어의 한 측면일 뿐입니다.온라인에는 이 좁은 공간에서 나보다 이것을 더 잘 설명하는 기사들이 많이 있습니다.여기에 하나가 있고 저는 다른 많은 것들이 있다고 확신합니다: http://www.cprogramming.com/tutorial/c/lesson8.html
C99 표준 n1124 6.3.2.1 p3부터
연산자 크기의 피연산자이거나 unary & 연산자이거나 배열을 초기화하는 데 사용되는 문자열 리터럴인 경우를 제외하고, "array of type" 유형을 가진 식을 배열 개체의 초기 요소를 가리키는 "pointer to type" 유형을 가진 식으로 변환하고 l 값이 아닙니다.어레이 개체에 레지스터 스토리지 클래스가 있으면 동작이 fi 해제됩니다.
오래 전에는 어레이의 주소를 얻기 위해 주소 연산자와 어레이의 주소를 사용해야 했지만 이제는 필요가 없기 때문에 a와 a의 값은 같습니다.요즘 어레이(이 경우 a)의 이름은 어레이 자체의 메모리 주소를 나타내며, 이 또한 &a에서 얻을 수 있습니다.컴파일러가 당신을 대신해서 다루는 것은 약어입니다.
언급URL : https://stackoverflow.com/questions/24467726/what-exactly-is-the-array-name-in-c
'programing' 카테고리의 다른 글
| SQL Server 데이터베이스에 'Object'를 저장할 수 있습니까? (0) | 2023.10.27 |
|---|---|
| Android 키 도구를 찾을 수 없습니다. (0) | 2023.10.27 |
| 웹 페이지가 JavaScript를 사용하여 다른 곳으로 이동하지 못하도록 방지 (0) | 2023.10.22 |
| 스프링-부트-스타터-테스트에서 데이터베이스 통합 테스트를 실행할 수 없음 (0) | 2023.10.22 |
| C로 인쇄하는 방법 (0) | 2023.10.22 |