Обработка C массивами очень отличается от Java, и вам придется соответствующим образом скорректировать свое мышление. Массивы в C не являются первоклассными объектами (т. Е. Выражение массива не сохраняет его «массивность» в большинстве контекстов). В C выражение типа «N-элементный массив из T
» будет неявно преобразовано («распад») в выражение типа «указатель на T
», за исключением случаев, когда выражение массива является операндом sizeof
или унарных &
операторов, или если выражение массива является строковым литералом, используемым для инициализации другого массива в объявлении.
Между прочим, это означает, что вы не можете передать выражение массива функции и получить его как тип массива ; функция фактически получает тип указателя:
void foo(char *a, size_t asize)
{
// do something with a
}
int bar(void)
{
char str[6] = "Hello";
foo(str, sizeof str);
}
В вызове foo
выражение str
преобразуется из типа char [6]
в char *
, поэтому первый параметр foo
объявлен char *a
вместо char a[6]
. В sizeof str
, поскольку выражение массива является операндом оператора sizeof
, оно не преобразуется в тип указателя, поэтому вы получаете количество байтов в массиве (6).
Если вы заинтересованы в действительно , вы можете прочитать Dennis Ritchie's «Развитие языка C» , чтобы понять, откуда взялось это лечение.
Результатом является то, что функции не могут возвращать типы массивов, что прекрасно, поскольку выражения массива также не могут быть целью назначения.
Самый безопасный метод заключается в том, что вызывающий может определить массив и передать его адрес и размер функции, которая должна ее записать:
void returnArray(const char *srcArray, size_t srcSize, char *dstArray, char dstSize)
{
...
dstArray[i] = some_value_derived_from(srcArray[i]);
...
}
int main(void)
{
char src[] = "This is a test";
char dst[sizeof src];
...
returnArray(src, sizeof src, dst, sizeof dst);
...
}
Другой метод функция для распределения массива динамически и возврата указателя и размера:
char *returnArray(const char *srcArray, size_t srcSize, size_t *dstSize)
{
char *dstArray = malloc(srcSize);
if (dstArray)
{
*dstSize = srcSize;
...
}
return dstArray;
}
int main(void)
{
char src[] = "This is a test";
char *dst;
size_t dstSize;
dst = returnArray(src, sizeof src, &dstSize);
...
free(dst);
...
}
В этом случае вызывающий отвечает за освобождение массива с помощью функции библиотеки free
.
Обратите внимание, что dst
в приведенном выше коде является простым указателем на char
, а не указателем на массив из char
. C-указатель и семантика массива таковы, что вы можете применить индексный оператор []
к выражению типа указателя типа или ; оба src[i]
и dst[i]
будут обращаться к i
-му элементу массива (хотя только src
имеет тип массива).
Вы можете объявить указатель на N-элементный массив из T
и сделать что-то подобное:
char (*returnArray(const char *srcArr, size_t srcSize))[SOME_SIZE]
{
char (*dstArr)[SOME_SIZE] = malloc(sizeof *dstArr);
if (dstArr)
{
...
(*dstArr)[i] = ...;
...
}
return dstArr;
}
int main(void)
{
char src[] = "This is a test";
char (*dst)[SOME_SIZE];
...
dst = returnArray(src, sizeof src);
...
printf("%c", (*dst)[j]);
...
}
Несколько недостатков с приведенным выше. Прежде всего, более старые версии C ожидают, что SOME_SIZE
будет константой времени компиляции, что означает, что функция будет работать только с одним размером массива. Во-вторых, вы должны разыменовать указатель перед применением индекса, который загромождает код. Указатели на массивы работают лучше, когда вы имеете дело с многомерными массивами.
Если вы используете inlining SVG в CSS url(data:...)
или просто используете фон url(*.svg)
, вы можете вставлять их в DOM с помощью svg-embed .
Поддержка Chrome 11+, Safari 5+, FireFox 4+ и IE9 +.
Нет, это невозможно, но вы можете просто преобразовать <img>
в <svg>
, как указано ЗДЕСЬ , и вы можете просто получить доступ к узлам в svg в DOM.
Невозможно получить DOM ссылочного svg из элемента img
.
Если вы используете <object>
, <embed>
или <iframe>
, то вы можете использовать .contentDocument
(предпочтительнее), чтобы получить ссылку svg или .getSVGDocument
, которая может быть более совместима со старыми плагинами svg.
.contentDocument
может обращаться к внешнему SVG-файлу, на который ссылаются элементы <object>
и <iframe>
, но не с помощью элементов <embed>
, тогда как .getSVGDocument()
может получить доступ к одному из всех трех. Однако .getSVGDocument()
теперь устарел , поэтому его следует использовать только в том случае, если на самом деле требуется обработка элементов <embed>
. Также обратите внимание, что .contentDocument
является (нефункциональным) свойством, а .getSVGDocument()
является методом (и, следовательно, требует скобки).
– Andrew Willems
7 March 2016 в 07:58
<img/>
(например, если у вас нет контроля над ресурсом SVG), возможно, захочет узнать о добавлении идентификаторов SVG Fragement , например. «<img src="myimage.svg#svgView(preserveAspectRatio(none))" />
», который позволяет вам контролировать соотношение сторон, viewBox
и т. д. так же, как и в встроенных определениях SVG.
– brichins
16 June 2016 в 17:06
Я уверен, что это невозможно. Внешний SVG не является частью DOM в способе встроенного SVG, и я не верю, что вы можете получить доступ к дереву SVG DOM из загружаемого документа.
Что вы можете do загружает SVG как XML, используя запрос AJAX, и вставляет его в DOM в качестве встроенного SVG, после чего вы можете ходить и манипулировать. Этот пример D3 демонстрирует технику. Я думаю, что используемая здесь функция d3.xml()
более или менее эквивалентна jQuery $.ajax()
с dataType: "xml"
.
<object>
, <embed>
или <iframe>
для загрузки svg, все это позволяет вам получить DOM.
– Erik Dahlström
13 November 2011 в 16:54
element.childNodes
, похоже, не показывают открытую SVG DOM. У вас есть пример?
– nrabinowitz
14 November 2011 в 05:00
getSVGDocument
. Вы должны представить в качестве ответа - я думаю, что это более простой и более простой метод, чем мой.
– nrabinowitz
15 November 2011 в 05:43