2017-01-15 4 views
1

В C++ Primer 5th Edition, раздел 3.5, стр 115, он дает следующий пример:C++ Primer - Указатели и ссылки на массив

int *ptrs[10]; // ptrs is an array of ten pointers to int 
int &refs[10] = /* ? */; // error: no arrays of references 
int (*Parray)[10] = &arr; // Parray points to an array of ten ints 
int (&arrRef)[10] = arr; // arrRef refers to an array of ten ints 

я понял почти все exemples, за исключением одного:

int (*Parray)[10] = &arr; // Parray points to an array of ten ints 

чтобы указать на массив, я мог бы просто сделать что-то вроде:

int a[10]; 
int *p = a; 

Поскольку имя «а» также точка er к массиву, теперь p указывает на то же место, что указатель, обозначенный указателем, обозначенным именем «a».

Я попытался скомпилировать пример, приведенный в книге, и я ожидал, что с помощью:

int (*Parray)[10] = &arr; // Parray points to an array of ten ints 

будет иметь тот же эффект, как и в примере, который я дал. Проблема заключается в том, что не бывает, вот код:

#include <iostream> 

using namespace std; 

int main(int argc, char const *argv[]) { 

    int arr[10] = {1,1,1,1,1,1,1,1,1,1}; 
    int *ptrs[10]; 
    int (*Parray)[10] = &arr; 
    int (&arrRef)[10] = arr; 

    cout << *(Parray + 1) << endl; 
    cout << Parray[1] << endl; 

    return 0; 
} 

Этот код компилируется, и дает следующий результат:

0x7fff5c4a2ab8 
0x7fff5c4a2ab8 

Может кто-нибудь объяснить, что именно:

int (*Parray)[10] = &arr; // Parray points to an array of ten ints 

является ? и что я могу с этим сделать?

ответ

1

Может кто-нибудь объяснить, что именно:

int (*Parray)[10] = &arr; // Parray points to an array of ten ints 

это? и что я могу с этим сделать?

Тип Parray является int (*)[10], то есть он может быть назначен только указатель на объект типа int [10].

Итак, у вас есть указатель, указывающий на начало массива (как получено &arr) из 10 элементов.

И способ доступа к элементам arr через Parray потребует от вас первого разыменования указателя Parray для получения arr который можно индексировать в:

Поэтому делать

(*Parray)[5] = 546; 

назначает 5-й элемент до 546, в результате чего будет выполняться следующее выражение.

arr[5] = 546; 

Как видно here.

1

Это просто указатель на массив с определенными элементами. Вы писали, что можете просто использовать указатель int *p = a; Это правильно, но этот указатель может указывать не только на определенный массив. Технически указатель p указывает на первый адрес первого элемента массива. int(*Parray2)[10] указатель только на массив с 10 элементами, потому что сигнатура статического массива T (&) [N]. Использование подписи массива можно написать, например, метод, который может вернуть размер статического массива:

template < size_t N, typename T > size_t GetSize(T(&)[N]) 
{ 
    return N; 
} 
... 
int arr[10] = { 1,1,1,1,1,1,1,1,1,1 }; 
auto sz = GetSize(arr); 

Если вы хотите работать с указателем, вы можете использовать его по-разному, но Int (* Parray2) [ 10] можно указать только на массив из 10 элементов:

int arr[10] = { 1,1,1,1,1,1,1,1,1,1 }; 
int arr2[11] = { 1,1,1,1,1,1,1,1,1,1,1 }; 

int *bare_ptr1 = arr; // legal 
int *bare_ptr2 = new int(); // legal 
int *bare_ptr3 = arr2; // legal 

int(*Parray)[10] = &arr; // legal 
int(*Parray2)[10] = new int(); // compile error 
int(*Parray3)[10] = arr2; // compile error 

cout << bare_ptr1 << endl; 
cout << &arr[0] << endl; 
cout << *(Parray + 0) << endl; 
cout << Parray[0] << endl; 

, если вы хотите, чтобы увидеть разницу адресов вы можете получить адрес PArray и адрес массива. Эти адреса должны быть разными.

cout << &Parray << endl; // address of the pointer which points to the array 
cout << &arr << endl; // addres of the first element in the array 
Смежные вопросы