비디오: [C/C++ 강좌] 25강. 배열과 포인터와의 관계 2024
배열의 이름은 배열 자체에 대한 포인터입니다. 배열 는 메모리에 저장된 일련의 변수입니다. 배열 이름 은 첫 번째 항목을 가리 킵니다.
이것은 포인터에 대한 흥미로운 질문입니다. 다음 행과 같은 함수 헤더를 가질 수 있으며 sizeof를 사용하여 배열에있는 요소의 수를 결정할 수 있습니까? 그렇다면이 함수는 호출자가 배열의 크기를 지정할 필요가 없습니다.
이 애플리케이션을 실행하면 다음과 같이 표시됩니다.
함수 외부에서 코드는 배열의 크기가 40 바이트임을 압니다. 하지만 코드가 배열 내부에있는 크기가 4라고 생각하는 이유는 무엇입니까? 그 이유는 배열을 전달하는 것처럼 보일지라도 실제로
포인터
를 배열에 전달하기 때문입니다. 포인터의 크기는 단지 4이며, 그래서 그것은 최종 출력물 라인이 출력하는 것입니다.배열 선언은 약간의 특이성을 가지고 있습니다. int MyNumbers [5]와 같이 명확한 수의 요소를 제공하여 배열을 선언 할 때. 컴파일러는 배열이 있음을 알고 sizeof 연산자는 전체 배열의 크기를 제공합니다. 배열 이름은
포인터와 배열 모두입니다. 하지만void ProcessArray (int Numbers []) {
와 같이 배열 크기가없는 함수 헤더를 선언하면 컴파일러는이를 단순히
포인터 와 같이 처리합니다. 이 마지막 줄은 사실 다음 줄과 같습니다. void ProcessArray (int * Numbers) {
따라서 두 줄 중 하나가 선언 한 함수 내에서 다음 두 줄의 코드는
: 숫자 [3] = 10; * (Numbers + 3) = 10; 이 같은 의미는 배열에서 extern 선언을 사용하는 경우 (예:
extern int MyNumbers [];
그리고 나서이 배열의 크기를 취하면 컴파일러는 혼란 스러울 것이다. 예를 들면 다음과 같습니다. 두 개의 파일이있는 경우 숫자입니다. cpp와 main. cpp, 여기서 숫자. cpp는 배열과 main을 선언합니다. cpp가 Array02 예제에서와 같이 외부에서 선언하면 sizeof를 호출하면 컴파일러 오류가 발생합니다. #include using namespace std; extern int MyNumbers []; int main (int argc, char * argv []) {cout << sizeof (MyNumbers) << endl; 코드:: 블록에서 gcc 컴파일러가 다음 오류를 표시합니다.
오류: 'sizeof'가 불완전한 유형 'int []'에 잘못 적용되었습니다.
해결책은 크기를 지정하는 것입니다. 대괄호 안의 배열크기가 다른 소스 코드 파일과 동일한 지 확인하십시오! 번호를 변경하여 컴파일러를 가짜로 만들면
에 오류가 발생하지 않습니다
. 그러나 이것은 잘못된 프로그래밍 스타일이며 오류를 묻는 것입니다.
배열
는 단순히 메모리에서 서로 인접한 일련의 변수이지만 배열의
이름은
실제로 배열의 첫 번째 요소에 대한 포인터입니다. 이름을 포인터로 사용할 수 있습니다. 그러나 포인터로 작업해야하는 경우에만 수행하십시오. 어쨌든 * (Numbers + 3) = 10과 같이 암호화 된 코드를 작성할 이유가 없습니다.. 그 반대도 마찬가지입니다. 이 함수를 보자. void ProcessArray (int * Numbers) {cout << numbers [1] << endl;} 이 함수는 포인터를 매개 변수로 받지만 배열로 접근한다. 다시 말하지만, 이와 같은 코드를 작성하지 마십시오. 대신
이 코드가 작동하는 이유 를 이해해야합니다. 그렇게하면 배열에 대한 깊은 지식과 컴퓨터 내부에서의 배열에 대한 지식을 얻게되며이 지식은 적절하게 작동하는 코드를 작성하는 데 도움이됩니다. 배열 이름은 단지 포인터 일 뿐이지 만 정수 배열의 이름은 정수에 대한 포인터와 완전히 똑같지 않습니다. 다음 코드 행을 확인하십시오 (Array03 예제에서 찾을 수 있음). int LotsONumbers [50]; int x; LotsONumbers = & x; Lotsonumbers
포인터
를 다른 것으로 지정하십시오: 정수로 선언 된 것이 있습니다. 컴파일러는이 작업을 수행 할 수 없습니다. 당신은 오류가 발생합니다. LotsONumbers가 int * LotsONumbers로 선언 된 경우에는 그렇지 않습니다. 이 코드가 작동합니다. 그러나 작성된 것처럼이 코드는 컴파일러 오류를 발생시킵니다. 믿거 나 말거나, 여기에 컴파일러 오류가 있습니다:: Blocks:
오류: 'int *'를 'int [50]'에 할당 할 때 호환되지 않는 유형입니다. 이 오류는 컴파일러에서 int *와 int []의 두 가지 유형을 확실하게 구분할 수 있습니다. 그럼에도 불구하고, 배열 이름은 실제로 포인터이며, 당신은 그것을 하나의 이름으로 사용할 수 있습니다; 재 지정과 같은 일반 포인터로 할 수있는 모든 작업을 수행 할 수 없습니다. 배열을 사용할 때는 다음 정보를 참고하십시오. 다음은 배열을 버그없이 유지하는 데 도움이됩니다.
코드 일관성 유지. 예를 들어, 정수를 가리키는 포인터를 선언하면 배열로 취급하지 마십시오.
명확하고 이해할 수있는 코드를 작성하십시오. 포인터를 전달하면 & (MyNumbers [0])와 같이 코드가 명확 해지면 첫 번째 요소의 주소를 가져 오는 것이 좋습니다. 다만 MyNumbers와 동일하지만 말입니다.
배열을 선언 할 때, 배열을 취하는 함수를 쓰지 않는 한 항상 괄호 안에 숫자를 넣으십시오. extern 키워드를 사용하여 배열을 선언 할 때는 배열 크기를 대괄호 안에 넣으십시오. 그러나 일관성있게하십시오! 한 번에 하나의 번호를 사용하고 다른 번호는 다른 번에 사용하지 마십시오. 일관성을 유지하는 가장 쉬운 방법은 const int와 같은 상수를 사용하는 것입니다. ArraySize = 10; 일반적인 헤더 파일에 다음 배열 선언에 사용: int MyArray [ArraySize];.