2016-01-14 2 views
4

Что такое: int (*b)[100], и что объясняет этот код для создания этого результата?Что означает: int (* b) [100]

#include <iostream> 
void foo(int a[100]) 
{ 
    a [1]= 30 ; 
    std::cout<<a[1]<< std::endl; 
} 

void boo(int a[100]) 
{ 
    std::cout<<a[1]<< std::endl; 
} 

int main() 
{ 
    int (*b)[100] = (int (*) [100]) malloc(100 * sizeof(int)); 
    *b[1] = 20; 
    std::cout<< *b[1] << "\t" << b[1] << std::endl; 
    foo(*b); 
    boo(*b); 
    std::cout<< *b[1] << "\t" << b[1] << std::endl; 
} 

Приведенный выше код выхода:

20 0x44ba430 
30 
30 
20 0x44ba430 
+7

Вы можете использовать http://cdecl.org, чтобы узнать, что означает это определение. – ForceBru

+4

Если вы попытаетесь изучить C++, вы можете пропустить это и проверить вместо этого 'std :: vector '. –

ответ

3

int foo[100]; объявляет foo как массив из 100 штук. Тип foo - int [100] (просто удалите foo из его объявления).

int (*b)[100]; заявляет *b как массив из 100 штук. И это означает, что b - это указатель для такого массива. Таким образом, вы можете написать b = &foo; например. Тип b - int (*)[100] (опять же, просто удалите b из его декларации).

Но просто указывать на массив, как в приведенном выше примере, не очень интересно, потому что указатель на первый элемент foo (т. Е. Указатель на int) достаточен для доступа к foo. Нет необходимости в указателе на массив. Вместо этого b интересно динамически выделять массив из int [100]. Например:

b = (int (*) [100]) malloc(25 * sizeof(int [100])); // allocates an array of 25 int [100] 
b[0][99] = 99; // correct 
... 
b[24][99] = 24099; // correct 
b[24][100] = 24100; // incorrect because each b[i] is an array of 100 integers 
b[25][0] = 25000; // incorrect because b is an array of 25 elements (an each element is an array) 

Таким образом, ваша программа неправильно, потому что вы выделили массив одногоint [100] только (на самом деле, 100 * sizeof(int) == sizeof(int [100])). Таким образом, вы можете написать эти инструкции, которые идентичны:

b[0][0] = 0; 
*(b[0]) = 0; 
*b[0] = 0; 

Но *b[1] неверен.

13
  • int (*b)[100] представляет собой указатель массива, указатель, который может указывать на массив из 100 межд.
  • *b[1] = 20; - это серьезная ошибка приоритета оператора, которая читается за пределами массива. Это должно было быть (*b)[1].
+0

@ 2501 Действительно. Возможно, однажды C++ догонит C и поддерживает VLA :) – Lundin

+0

@Lundin Я бы хотел видеть VLA на C++, хотя я запрещаю себе использовать их в стеке, просто указатели vla в выделенную память. – 2501

+1

@ 2501 или вы можете просто программировать с идиомами C++ и использовать вектор. – StoryTeller

4

int (*b)[100] является указателем на массив из 100 элементов. Переменная b указывает на выделенную память, которая выделяется malloc: malloc(100 * sizeof(int));, но это выделяет только одну строку.

Проблема в следующей строке: *b[1] = 20;, это идентично b[1][0], что выходит за пределы массива. Это вызывает неопределенное поведение в программе.

2

int (*b)[100] объявляет b указателем на массив из 100 целых чисел.

Линия с malloc выделяет память, на которую указывает указатель b. *b разыгрывает указатель и, таким образом, дает нам недавно выделенную память. b[1] - это всего лишь адрес, его можно переписать как b + 1. Этот адрес составляет 100 целых чисел, кроме того, что указывает b.

foo принимает pointer to int и присваивает значение 30 во второй слот, начинающийся с этого указателя (адрес чтения). Оба foo и boo просто выводят то, что находится в этом втором слоте из этого указателя. изменив последнюю строку на

std::cout<< *b[1] << "\t" << b[0] << std::endl;

и увидеть разницу, что адрес b[0] и что адрес b[1], вы обнаружите, что они отделены друг от друга 100 целых

Try. В моем компиляторе я вижу разницу в 0x190, которая составляет 400 байт (целое число составляет 4 байта, а 100 целых - 400 байт).

+0

* "* b [1] дает нам второй слот в массиве" *, приоритет оператора не согласуется с вами – StoryTeller

+0

@StoryTeller благодарит человека предупреждения –

+0

Если 'b [1]' были действительными (например, если у вас есть 'int a [2] [100]; int (* b) [100] = a; '), это не будет адрес, это будет 100-элементный массив. В этом случае '* b [1]' является недопустимым разыменованием. Допустимым назначением будет '(* b) [1] = 20;'. – molbdnilo

3

Существует разница между int (* b) [100]; и int * b [100];

int (*b)[100]; // A pointer to an array of 100 integers. 

int *b[100]; // An array of 100 int pointers. 
0

Я предпочитаю понимание странные заявления первых typedef'ing их, а затем пытается связать и посмотреть.

Например,

typedef unsigned char uint8_t; // 8 bit memory 
typedef uint8_t b[100]; // create an array b having 100 elements, 
         // where each element occupies 8 bit memory 
typedef uint8_t *e;//create a pointer that points to a 8 bit memory 

main() 
{ 
b *c; //create a pointer c pointing to a type b-"array having 100 elements 
     // & each element having 8 bit memory". This is equivalent to what 
     // you said - (*b)[100]. Like just moving the * 
b d;//create an array d having 100 elements of 8 bit memory 
e f[100];//create an array of 100 pointers pointing to an 8 bit memory 
} 

This также может помочь.

Смежные вопросы