Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
#1

С++ VLA и прочее... - C++

30.11.2012, 00:17. Просмотров 1392. Ответов 51
Метки нет (Все метки)

 Комментарий модератора 
Перенесено из Порекомендуйте компилятор


Dev-C++ меня удивляет. Вот такой код компилирует без ошибок и предупреждений:
C++
1
2
3
4
5
6
7
int main()
{
    int m;
    int arr[m];
    
    return 0;
}
А такой и выполняет:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main()
{
    int m;
    cin >> m;
    int arr[m];
    
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.11.2012, 00:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос С++ VLA и прочее... (C++):

Скремблирование и прочее - C++
Добрый день, помогите разобраться. Нужно написать программу для скремблирование файлов. Но перед этим вопрос: как из исходного файла...

Рекурентная формула и прочее - C++
Добрый день , пишу вам для получения помощи! Никак не могу сделать рекурентную формулу и программу под выражением &quot;б&quot;Помогите...

Дирректива define и прочее - C++
Помогите пожалуйста решить задание, никогда раньше с такими не сталкивался! =( 1) Даны целые числа x, у и вещественное число z....

Указатель на массив char и прочее - C++
Страуструп для проверки прочитанного в заданиях после одной из глав просит через typedef сделать пару объявлений и вот как делать некоторые...

Стиль написания кода(читабельность и прочее) - C++
Недавно делал тестовое задание для поиска работы, но мне сказали, что код не совсем корректно написан. Задание:Написать рекурсивный и не...

Размер примитивных типов, выравнивание и прочее - C++
Как обычно борются с тем, что примитивный тип от компа к компу разного размера? Допустим, если записывают данные по сети или в двоичные...

51
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,494
30.11.2012, 00:40 #2
Второй код считаю нормальным.
Первый говнокод конечно, но при чём тут IDE? За вывод предупреждений она не ответственна, а то щас наговоришь тут. За предупреждения ответственен компилятор (там стоит gcc). Открываешь в DEV параметры компилятора и пишешь (это нужно уметь делать безусловно) -Wall в опциях и будет круто; в обоих случаях выведутся предупреждения.

В книжке Артура Гриффитса подробно всё описано.
0
Dima_c8
4 / 4 / 0
Регистрация: 17.12.2011
Сообщений: 148
30.11.2012, 00:43 #3
кстати вроде по теме а как там в деве запустить функцию InitCommonControls а то не работает
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 01:03  [ТС] #4
Цитата Сообщение от kravam Посмотреть сообщение
Второй код считаю нормальным.
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?

Цитата Сообщение от kravam Посмотреть сообщение
Открываешь в DEV параметры компилятора и пишешь (это нужно уметь делать безусловно)
Особенно начинающему... Научи, где что писать.

Добавлено через 8 минут
Цитата Сообщение от kravam Посмотреть сообщение
Первый говнокод конечно, но при чём тут IDE? За вывод предупреждений она не ответственна, а то щас наговоришь тут. За предупреждения ответственен компилятор (там стоит gcc).
Начинающий не будет возиться с подключением другого компилятора к IDE. Для него это всё - IDE.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 676
Регистрация: 29.11.2010
Сообщений: 12,328
30.11.2012, 01:23 #5
Цитата Сообщение от alsav22 Посмотреть сообщение
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?
Оно преобразует переменную и создает статический массив на момент обращения. А void main по-умолчанию и include "stdafx" какой-то куда лучше. А ведь, пропустив автоматом пункт, где надо убрать галочку (а новичок побоится вмешиваться в дефолтные настройки), абсолютно нормальный код не скомпилится. Не говоря уж о том, что студия пытается везде пропихнуть свои стандарты, пугая списком варнингов типа юзай непереносимое printf_s заместо абсолютно нормального printf. Да, можно довести студию до ума, но это уже разбираясь в настройках. Ну и второй код с VLA (variable length array) не считаю слишком критичным. Уж кто бы говорил о стандартах, так это точно не продукты от Microsoft.
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 01:35  [ТС] #6
Цитата Сообщение от MrGluck Посмотреть сообщение
А ведь, пропустив автоматом пункт, где надо убрать галочку (а новичок побоится вмешиваться в дефолтные настройки), абсолютно нормальный код не скомпилится
Поэтому я всем советую создавать пустой проект, там галочки не нужно ставить.
Цитата Сообщение от MrGluck Посмотреть сообщение
Не говоря уж о том, что студия пытается везде пропихнуть свои стандарты
С этим согласен.
Цитата Сообщение от MrGluck Посмотреть сообщение
Уж кто бы говорил о стандартах, так это точно не продукты от Microsoft.
С этим тоже согласен, но насчёт размерности массива, причёт здесь Microsoft? Об этом разговоры здесь были и , если я не прав, пусть поправят, но я так понял, что именно по стандарту размер статического массива должен быть величиной константной, а значит известной на момент компиляции.
0
activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
30.11.2012, 01:39 #7
alsav22, а что тут собственно не устраивает? память, отведенная под m уже содержит значения, то что кододел ее не инициализировал своим значением, это его проблемы.
C++
1
2
3
4
5
6
7
int main()
{
    int m;
    int arr[m];
    
    return 0;
}
Как заметил MrGluck, VLA даже в Сишке есть. Начиная с Си99 это очень корректный код.
C
1
2
3
4
5
void f(size_t n)
{
    int array[n];
    ...
}
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 02:52  [ТС] #8
Вопрос не о том, что кого устраивает или не устраивает. Вопрос о том, как правильно. Как тогда это понимать? http://www.cplusplus.com/doc/tutorial/arrays/
NOTE: The elements field within brackets [] which represents the number of elements the array is going to hold, must be a constant value, since arrays are blocks of non-dynamic memory whose size must be determined before execution. In order to create arrays with a variable length dynamic memory is needed, which is explained later in these tutorials.
Добавлено через 15 минут
Вот эти объяснения, как понимать? Массивы. Статические и динамические
0
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 676
Регистрация: 29.11.2010
Сообщений: 12,328
30.11.2012, 03:02 #9
alsav22, http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1336.pdf
However, an object declared with the static storageclass specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a
VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
extern int n;
int A[n]; // invalid file scope VLA
extern int (*p2)[n]; // invalid file scope VM
int B[100]; // invalid file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
typedef int VLA[m][m]; // valid: block scope typedef VLA
struct tag {
int (*y)[n]; // invalid: y not ordinary identifier
int z[n]; // invalid: z not ordinary identifier
};
int D[m]; // valid: auto VLA
static int E[m]; // invalid: static block scope VLA
extern int F[m]; // invalid: F has linkage and is VLA
int (*s)[m]; // valid: auto pointer to VLA
extern int (*r)[m]; // invalid: r has linkage and points to VLA
static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}
Добавлено через 5 минут
Кстати, на С++, по-моему, даже в С++11 это не по стандарту. Но это тот же сценарий, что и long long int.
0
kravam
быдлокодер
1700 / 887 / 45
Регистрация: 04.06.2008
Сообщений: 5,494
30.11.2012, 12:11 #10
Цитата Сообщение от alsav22 Посмотреть сообщение
Размер статического массива должен быть известен на момент компиляции. Иначе, как под него память выделять?
А как вообще память под массивы выделяется? Мне кажется функция начинает работать и только тогда выделяется память под массив в стеке. Скорее всего просто указатель на верхушку стека просто-напросто уменьшается на нужное количество байт (в данном случае на m байт). Всё память выделена. ВО ВРЕМЯ РАБОТЫ ФУНКЦИИ main. Проверить так это ли нет- в отладчике сложно. Но можно в том же отладчике посмотреть, откуда функция берёт элементы массива (хотя тут m известно на начало работы, но это не главное, главное, ГДЕ ВЫДЕЛЯЕТСЯ ПАМЯТЬ ПОД МАССИВ)

C++
1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    int m= 0X100;
    int arr[m];
    printf ("%d\n", arr [0]); 
    return 0;
}
А выделяется она в стеке; и она может выделиться так, а может выделиться эдак. Отсюда вывод: выделяется она во время работы функции. И следующий вывод: поэтому ничто (кроме больших размеров) не мешает тому, чтобы размер массива (величина стека, выделенного под него) был определён во время работы функции.

Цитата Сообщение от alsav22 Посмотреть сообщение
Особенно начинающему... Научи, где что писать.
Я уже научил. Уже можно по тому, что я сказал, найти настройки компилятора и место, где прописывать опции, DEV компактна довольна. Там негде особо блудить.
И ещё научу, надо будет. Скажем так: и там и там начинающий сталкивается с определёнными трудностями. Так по мне пусть он лучше некорректным кодом пропишет память (а рано или поздно он всё равно это сделает) и научится, как этого избегать (твой первый код), чем увидит чудо-юдо-рыбу-кит например: strcpy_s, которая ни в одном учебнике по C не упоминается.

Цитата Сообщение от alsav22 Посмотреть сообщение
Начинающий не будет возиться с подключением другого компилятора к IDE. Для него это всё - IDE.
Ну и пусть работает с тем, что дают, а подключает ПОТОМ, когда станет неначинающим.
0
XRuZzz
Антикодер
681 / 583 / 29
Регистрация: 15.09.2012
Сообщений: 2,531
30.11.2012, 12:21 #11
+1 голос за gcc в линухе, на Gentoo библиотеки ставятся автоматически системой портов, что уменьшает количество проблем при их подключении.
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 20:15  [ТС] #12
Цитата Сообщение от kravam Посмотреть сообщение
Мне кажется функция начинает работать и только тогда выделяется память под массив в стеке
Неправильно кажется. Память в стеке, под переменные, выделяется до начала работы main(). В этом всё и дело. Как выделить память, если размер её неизвестен?
0
Миниатюры
С++ VLA и прочее...  
activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
30.11.2012, 20:19 #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Память в стеке, под переменные, выделяется до начала работы main().
да ну, а stack overflow придумали троли
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
30.11.2012, 20:21 #14
Второй код считаю нормальным.
Ты может и считаешь, а стандарт C++ - нет.
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.11.2012, 21:23  [ТС] #15
Цитата Сообщение от MrGluck Посмотреть сообщение
owever, an object declared with the static storageclass specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a
VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.Код C++

extern int n;
int A[n]; // invalid file scope VLA
extern int (*p2)[n]; // invalid file scope VM
int B[100]; // invalid file scope but not VM
void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
typedef int VLA[m][m]; // valid: block scope typedef VLA
struct tag {
int (*y)[n]; // invalid: y not ordinary identifier
int z[n]; // invalid: z not ordinary identifier
};
int D[m]; // valid: auto VLA
static int E[m]; // invalid: static block scope VLA
extern int F[m]; // invalid: F has linkage and is VLA
int (*s)[m]; // valid: auto pointer to VLA
extern int (*r)[m]; // invalid: r has linkage and points to VLA
static int (*q)[m] = &B; // valid: q is a static block pointer to VLA
}
MrGluck, не могли бы вы хоть как-то прокоментировать эту цитату. Для меня, как начинающего, сложно понять о чём тут речь.
0
30.11.2012, 21:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.11.2012, 21:23
Привет! Вот еще темы с ответами:

Инкремент, декремент и прочее. A+++ - что означают это три плюса - C++
день добрый х) в задании попалась такая операция: a+++ = b%2 так вот. что, собственно, означают это три плюса?я знаю что есть инкремент, но...

Для чего нужны переменные, и прочее типа, константа, типы , массивы и т.к.д ? - C++
Для чего нужны переменные, и прочее типа, константа, типы , массивы и т.к.д

Для чего нужно писать в int main() в скобках всякие args потом объявлять переменные, и прочее. Для чего если можно в сборках это все обьявлять. - C++
Для чего нужно писать в int main() в скобках всякие args потом объявлять переменные, и прочее. Для чего если можно в сборках это все...

Связка БД и прочее - MS Access
Здравствуйте. Я впервые занимаюсь БД и мне хотелось бы узнать, как осуществить следующее: Например создание БД для железнодорожных касс....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru