Чтобы слишком сильно сфокусироваться на этом дробном узоре (в качестве индикатора внутренних деталей хэша), может быть запутанным. Существует один аспект «скалярного значения» хеша, который важен для потенциально каждой программы Perl, и если это считается истинным в булевом контексте , см. Пример:
if (%h) {
print "Entries in hash:\n";
for my $k (sort keys %h) {
print "$k: $h{$k}\n";
}
}
В perldoc perldata, раздел Scalar-values , вы можете прочитать, что
[...] Булевский контекст - это просто особый вид скаляра контекст, в котором когда-либо не выполняется преобразование в строку или число.
blockquote>и некоторые абзацы позже
Если вы оцениваете хэш в скалярном контексте, он возвращает false, если хэш пуст. Если есть пары ключей / значений, он возвращает true [...]
blockquote>
То, как вы его написали сейчас, называются «взломом структурирования», пока C99 - до «C99» как «гибкий элемент массива». Причина, по которой вы получаете ошибку (возможно, в любом случае), это то, что она должна сопровождаться запятой:
#include <stdlib.h>
struct my_struct {
int n;
char s[];
};
, когда вы выделяете пространство для этого, вы хотите выделить размер структуры Plus Количество пространства, которое вы хотите для массива:
struct my_struct *s = malloc(sizeof(struct my_struct) + 50);
В этом случае гибкий элемент массива представляет собой массив CHAR и SIZEOF (CHAR) == 1, поэтому вам не нужно умножить по его размеру, но так же Любой другой Malloc, который вам нужно, если бы это был массив некоторых других типов:
struct dyn_array {
int size;
int data[];
};
struct dyn_array* my_array = malloc(sizeof(struct dyn_array) + 100 * sizeof(int));
Редактирование: Это дает другой результат от изменения элемента на указатель. В этом случае вы (как правило) нуждаются в двух отдельных распределениях, один для самого структуры, и один для «дополнительных» данных, которые необходимо указывать на указатель. Используя гибкий элемент массива, вы можете выделить все данные в одном блоке.
Вы должны решить, что вы пытаетесь сделать в первую очередь.
Если вы хотите иметь структуру с указателем на AS [Независимый] массив внутри, вы должны объявить его как
struct my_struct {
int n;
char *s;
};
в этом случае, вы можете создать фактический объект Struct Crust, как угодно, пожалуйста (как автоматическую переменную Например)
struct my_struct ms;
и затем выделите память для массива независимо
ms.s = malloc(50 * sizeof *ms.s);
на самом деле, нет общего необходимости выделить память массива динамически
struct my_struct ms;
char s[50];
ms.s = s;
, все зависит от того, какого рода жизни вам нужно от этих объектов. Если ваша структура автоматическая, то в большинстве случаев массив также будет автоматически. Если объект структуры принадлежит , память массива, просто нет смысла делать в противном случае. Если сама структура динамически, то массив также должен обычно быть динамичным.
Обратите внимание, что в этом случае у вас есть две независимые блоки памяти: структура и массив.
Совершенно другой подход будет использоваться идиома «stack Hack». В этом случае массив становится неотъемлемой частью структуры. Оба проживают в одном блоке памяти. В C99 структура будет объявлена как
struct my_struct {
int n;
char s[];
};
и создать объект, который вы должны придеться, чтобы распределить все это динамически
struct my_struct *ms = malloc(sizeof *ms + 50 * sizeof *ms->s);
, размер блока памяти в этом случае рассчитывается для размещения элементов структуры и трейлинг-массив запуска раз размер.
Обратите внимание, что в этом случае у вас нет возможности создавать такие структурные объекты как статические или автоматические объекты. Структы с гибкими элементами массива в конце могут быть выделены только динамически в C.
Ваше предположение о aritmics aritmectics, чем быстрее, а затем массивы абсолютно неверны. Массивы работают через указатель арифметики по определению, поэтому они в основном одинаковы. Более того, подлинный массив (не разлагается до указателя), как правило, немного быстрее, чем объект указателя. Значение указателя должно быть прочитано из памяти, в то время как местоположение массива в памяти является «известным» (или «рассчитанным») из самого объекта массива.
Указатель арифметика быстрее, чем массивы, да?
Не совсем - они на самом деле одинаковы. Массивы переводят на указатель арифметики при компиляции времени.
char test[100];
test[40] = 12;
// translates to: (test now indicates the starting address of the array)
*(test+40) = 12;
использование массива неуказанного размера только позволяется в конце структуры и только работает в некоторых компиляторах. Это - нестандартное расширение компилятора. (Хотя я думаю, что помню, что C++ 0x будет позволять это.)
массив не будет отдельным выделением для от структуры все же. Таким образом, необходимо выделить все из my_struct
, не только часть массива.
то, Что я делаю, просто дают массиву небольшой, но ненулевой размер. Обычно 4 для символьных массивов и 2, чтобы массивы wchar_t
сохранили выравнивание на 32 бита.
Затем можно принять заявленный размер во внимание массива, когда вы делаете выделение. Я часто не делаю на теории, что помои меньше, чем гранулярность, в которой работает диспетчер "кучи" в любом случае.
кроме того, я думаю, что вы не должны использовать sizeof (символ*) в вашем выделении.
Это - то, что я сделал бы.
struct my_struct {
int nAllocated;
char s[4]; // waste 32 bits to guarantee alignment and room for a null-terminator
};
int main()
{
struct my_struct * pms;
int cb = sizeof(*pms) + sizeof(pms->s[0])*50;
pms = (struct my_struct*) malloc(cb);
pms->nAllocated = (cb - sizoef(*pms) + sizeof(pms->s)) / sizeof(pms->s[0]);
}
Массивы будут решать указателям, и здесь вы должны определить s
как CHAR * S
. Конструкция в основном является контейнером, и должен (IIRC) быть фиксированным размером, поэтому наличие динамично размером массива внутри него просто невозможно. Поскольку вы MALLOC
в любом случае память, это не должно иметь никакого значения в том, что вы после.
В основном вы говорите, S
будет указывать местоположение памяти. Обратите внимание, что вы все еще можете получить доступ к этому позже, используя нотацию, подобную S [0]
.
Я должен заявить, что, хотя нет нового релиза каждые 2 месяца, как Роб заявил, что вы можете иногда испытывать это чувство. Хотя есть еще действие на гугл-группу и гитуб. Если что-то до Рождества было больше свежих лиц, начинающих вносить вклады, чем раньше (даже простые, такие как doco), это показывает мне, что может быть больше интереса, чем когда-либо, его просто то, что люди получают с этим.
Моя работа использует Subsonic (как 2.2, так и 3.0.0.3) в большинстве проектов, где мы контролируем его. У нас есть около 28 .net devs, и они все любят это (мы не попадаемся в то, что он не может сделать, как его не ORM/доступ к данным говорят per se.
Поскольку мы используем только Donsonic для низкоуровневого инструмента запроса, а не в качестве уровня доступа к данным, я полагаю, что мы не слишком тесно связаны с ним, если нам нужно заложить его, но у нас еще есть причина.
Моя точка зрения такова: Его действительно действительно легко использовать, легко подобрать, легко модифицировать, легкий инструмент запроса/ORM (в меньшей степени). Есть немного инструментов, которые имеют все эти свойства и, тем не менее, не запирают вас в миллион школ мысли о вещах. Из-за этого я не вижу, что он умирает в ближайшее время - это слишком привыкание инструмент, чтобы иметь на ремне летучей мыши.
Я активный фанатский буй звукозаписи и SubSonic Rocksorz My Sockorz!
Из-за этого я рекомендую SubSonic многим людям и буду продолжать. Хотя мы не используем его на чрезвычайно крупных проектах (больше по причинам непрерывности проекта, как вы упомянули, чем потому, что он не может выполнять работу)
-121--3085452-Пытались ли вы настроить команду - Q в качестве ускорителя в меню? Можете ли вы заставить ваше приложение ответить на него?
Я не положительный, но я думаю, что это работает в Linux и, вероятно, Windows с эквивалентным Alt - F4 . Мое приложение отвечает на «убойный» нажатие клавиши, я обрабатываю некоторый код очистки, а затем делаю программный System.exit ()
.
Если вы «просто» после изящной обработки выхода, вы можете также захотеть поймать WindowEvent
WINDOW _ CLOSING
, где традиционно «вы уверены?» все делается.
Я подозреваю, что компилятор не знает, сколько места ему потребуется выделить для s [], если вы решите объявить с ним автоматическую переменную.
Я согласен с тем, что сказал Бен, объявите вашу структуру
struct my_struct {
int n;
char s[1];
};
Также, чтобы уточнить его комментарий о месте хранения, заявив, что char * s
не поместит структуру на стек (поскольку он динамически распределяется) и распределяет s
в куче, что он будет делать, так это интерпретировать первый размер(char *)
байт массива в качестве указателя, так что вы не будете работать с данными, которые вы считаете, и, вероятно, будут фатальными.
Важно помнить, что, хотя операции над указателями и массивами могут быть реализованы одним и тем же путем, они не являются одним и тем же.
, сгенерированный код, будет идентичен (массив и PTR). Помимо того, что массив один не скомпилируется, это
и BTW - сделайте его C ++ и использовать вектор