1. На форумах писали, что int(*ptr)[10] - это указатель на массив из 10 элементов.
Но не проще ли в таком случае написать int ptr[10]?
Может быть и проще, но я не понимаю роль скобок.
2. А еще там, в изучаемом материале, есть следующий синтаксис:
int(*ptr)[10]=new int[5][10].
Если судить по логике вышенаписанных слов, то это можно расшифровать как:
в левой части равенства указатель на массив из 10 элементов = динамический двумерный массив [5][10]?
2.1. Обязательно ли крайние правые индексы в обеих частях равенства должны совпадать?
Я об индексе [10].
Прошу прощения за свое невежество. Буду очень признателен за объяснения.
C/C++
Объсните пожалуйста значение скобок в int(*ptr)[10] и разницу с int(*ptr)[10]=new int[5][10]. (Подробности в описании)
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
/* Это матрица у которой количество строк определяется
* в процессе выполнения программы, а количество элементов
* в этих строках известно к началу компиляции и неизменно
* в процессе её выполнения.
* Под такую матрицу память выделяется в куче.
* Такая матрица, как уже говорилось ранее, располагается
* в памяти последовательно единым кусом.
* int ptr[10]; является статическим массивом, который
* расположен в программном стеке.
*/
int n = 4; // переменная
const int m = 5; // котнстанта
int(*ptr)[m] = new int[n][m];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
ptr[i][j] = i + j + 1;
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << setw(4) << ptr[i][j];
}
puts("");
}
delete[] ptr;
system("pause > nul");
}
#include <iomanip>
using namespace std;
int main() {
/* Это матрица у которой количество строк определяется
* в процессе выполнения программы, а количество элементов
* в этих строках известно к началу компиляции и неизменно
* в процессе её выполнения.
* Под такую матрицу память выделяется в куче.
* Такая матрица, как уже говорилось ранее, располагается
* в памяти последовательно единым кусом.
* int ptr[10]; является статическим массивом, который
* расположен в программном стеке.
*/
int n = 4; // переменная
const int m = 5; // котнстанта
int(*ptr)[m] = new int[n][m];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
ptr[i][j] = i + j + 1;
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << setw(4) << ptr[i][j];
}
puts("");
}
delete[] ptr;
system("pause > nul");
}
int ptr [10] - статический одномерный массив интов на 10 элементов.
int *ptr[10] - статический одномерный массив указателей типа инт на 10 элементов. Из него можно сделать двумерный массив с явнозаданным первым индексом [10].
int(*ptr)[10] - указатель на массив по 10 элементов каждый. Из него можно сделать двумерный массив с явнозаданным вторым индексом [x][10];
int *ptr1 [10];
for (int i=0;i<10;i++)
ptr1 [i] = new int [20]
В итоге получаем двумерный полудинамический массив 10*20 (1 массив на 10 хранится в стеке, и десять отдельных массивов по 20 элементов в куче)
int (*ptr2)[10];
ptr2 = new int [20][10] - двумерный динамический массив 20*10. Насколько я понял, эта конструкция отличается от первой тем, что сразу создается непрерывная область памяти на 200 int, которая ведет себя как двумерный массив. Но это не точно!
Теперь чтобы очистить память первого массива, нужно 10 раз удалять указатели на каждый отдельный массив.
А для второго - только один указатель.
Как помним динамический массив типа ** нужно удалять сразу двумя верхними способами.
int *ptr[10] - статический одномерный массив указателей типа инт на 10 элементов. Из него можно сделать двумерный массив с явнозаданным первым индексом [10].
int(*ptr)[10] - указатель на массив по 10 элементов каждый. Из него можно сделать двумерный массив с явнозаданным вторым индексом [x][10];
int *ptr1 [10];
for (int i=0;i<10;i++)
ptr1 [i] = new int [20]
В итоге получаем двумерный полудинамический массив 10*20 (1 массив на 10 хранится в стеке, и десять отдельных массивов по 20 элементов в куче)
int (*ptr2)[10];
ptr2 = new int [20][10] - двумерный динамический массив 20*10. Насколько я понял, эта конструкция отличается от первой тем, что сразу создается непрерывная область памяти на 200 int, которая ведет себя как двумерный массив. Но это не точно!
Теперь чтобы очистить память первого массива, нужно 10 раз удалять указатели на каждый отдельный массив.
А для второго - только один указатель.
Как помним динамический массив типа ** нужно удалять сразу двумя верхними способами.
Владимир Сапрыкин
Большое спасибо за развернутый ответ.
Что такое:
•int ptr [10]- Одномерный массив из 10 элементов.
•int *ptr[10]- Одномерный массив из 10 неинициализированных указателей.
Я теперь вроде бы знаю.
1. Но по следующему все равно смутно понятен синтаксис.
"int(*ptr)[10] - указатель на массив по 10 элементов каждый."
Скобки здесь нужны, чтобы:
1) сначала создался массив int[10], а лишь только потом
2) Создавался указатель *ptr под этот массив?
2. «int(*ptr)[10] - указатель на массив по 10 элементов каждый. Из него можно сделать двумерный массив с явнозаданным вторым индексом [x][10];
int *ptr1 [10];
for (int i=0;i<10;i++)
ptr1 [i] = new int [20]»
1) или с любым иным количеством индексов, то есть так: [x1][x2][x3][10] ?
2) Но ведь int(*ptr)[10] это не одно и то же, что и int *ptr1 [10];
Что такое:
•int ptr [10]- Одномерный массив из 10 элементов.
•int *ptr[10]- Одномерный массив из 10 неинициализированных указателей.
Я теперь вроде бы знаю.
1. Но по следующему все равно смутно понятен синтаксис.
"int(*ptr)[10] - указатель на массив по 10 элементов каждый."
Скобки здесь нужны, чтобы:
1) сначала создался массив int[10], а лишь только потом
2) Создавался указатель *ptr под этот массив?
2. «int(*ptr)[10] - указатель на массив по 10 элементов каждый. Из него можно сделать двумерный массив с явнозаданным вторым индексом [x][10];
int *ptr1 [10];
for (int i=0;i<10;i++)
ptr1 [i] = new int [20]»
1) или с любым иным количеством индексов, то есть так: [x1][x2][x3][10] ?
2) Но ведь int(*ptr)[10] это не одно и то же, что и int *ptr1 [10];
Владимир Сапрыкин
3. Меня напрягает именно несоответствие индексов в левой и правой части.
int(*ptr)[10]=new int[5][10].
Ведь если в левой указатель на массив из 10 элементов, то как в правой части может быть двумерный массив [5][10]. Тут явное несоответствие.
int(*ptr)[10]=new int[5][10].
Ведь если в левой указатель на массив из 10 элементов, то как в правой части может быть двумерный массив [5][10]. Тут явное несоответствие.
Владимир Сапрыкин
Да, к сожалению или к счастью, соображалка у меня варит медленно. Прошу прощения за надоедливость и свое непонимание.
Вячеслав Фарима
1. как обьяснил высший разум - скобки нужны чтобы дать понять компилятору, что создается именно указатель, к которому можно применить двумерный итератор [][].
Типа: создай ка нам двумерный массив, но не явно, а только указатель на него.
2. int (*ptr)[10] если совсем честно - то это обычный одномерный динамический массив. С той только разницей, что он позволяет обращаться к своим элементам так, как если бы он был двумерным. Каждый его элемент это 10-ти кратный инт. И полный размер его должен быть кратным 10 соответственно.
А так как это одномерный массив, то конструкция с кучей индексов не применима.
А выражение ptr = new int [20][10] честно соответствует new int [200] или [20*10]. Но компилятор ругается на 200, что типа не та размерность. Хотя и так понятно что мы имеем ввиду.
Типа: создай ка нам двумерный массив, но не явно, а только указатель на него.
2. int (*ptr)[10] если совсем честно - то это обычный одномерный динамический массив. С той только разницей, что он позволяет обращаться к своим элементам так, как если бы он был двумерным. Каждый его элемент это 10-ти кратный инт. И полный размер его должен быть кратным 10 соответственно.
А так как это одномерный массив, то конструкция с кучей индексов не применима.
А выражение ptr = new int [20][10] честно соответствует new int [200] или [20*10]. Но компилятор ругается на 200, что типа не та размерность. Хотя и так понятно что мы имеем ввиду.
Вячеслав Фарима
Я сам недавно начал изучать с нуля С++, поэтому и сам узнаю много нового, пытаясь помочь другим.
А что за язык?
Похожие вопросы
- Язык С++ : есть ли разница между этими двумя операциями? 1) int m = (int)n; 2) int m = int(n).
- При присвоении i++; или ++i; разница есть а вот есть ли разница при присвоении int &i; int& i; int* i; int *i;
- Программа на C++ с переводом Char в Int и наоборот при переводе возвращает НИЧЕГО
- Различие указателей int *; и char *;
- Проверка на правильность расстоновки скобок C++
- Strlen для int массивов.(Си)
- Что за числа выводятся при переполнении int в C++?
- Никак не могу понять применение операции NEW и DELETE.
- Здраствуйте, я не понимаю что означает "int" и "main" можете обьяснить)
- Ошибка в динамическом массиве new[] и delete[] |С++ Builder
Я с понятием матрицы еще не встречался, в изучаемом материале просто говорится о динамическом выделении массива и ни слова о матрице. Сможете объяснить без этого понятия?
А также ответить на вопрос:
2.1. Обязательно ли крайние правые индексы в обеих частях равенства должны совпадать?
int(*ptr)[10]=new int[5][10].