Как найти конец массива

I’m making a dynamic array with int* data type using malloc(). But the problems is, how to know end of array?

There no an equivalent to for int* data type,so, how to do this? Pass size as out parameter of function?

halfer's user avatar

halfer

19.8k17 gold badges98 silver badges185 bronze badges

asked Apr 19, 2012 at 0:43

Jack's user avatar

1

C doesn’t manage array lengths, as some other languages do.

you might consider a structure for this:

typedef struct t_thing {
  int* things;
  size_t count;
} t_thing;

in use:

t_thing t = { (int*)malloc(sizeof(int) * n), n };

answered Apr 19, 2012 at 0:47

justin's user avatar

justinjustin

104k13 gold badges179 silver badges226 bronze badges

There is no «official» equivalent to for integers, but you can certainly use your own value. For example, if your integers represent distances then you can use -1 (not a valid distance) as a sentinel value to indicate the end of the array.

If your integer array can reasonably contain any int value, then you can pass back the size of the allocated array with an additional parameter to your function.

answered Apr 19, 2012 at 0:45

Greg Hewgill's user avatar

Greg HewgillGreg Hewgill

942k181 gold badges1140 silver badges1280 bronze badges

1

You can use NULL as an end value. You can add an integer to a struct with the array that tracks the number of entries. Or you can track the size separately. You can do it however you want.

answered Apr 19, 2012 at 0:47

David Schwartz's user avatar

David SchwartzDavid Schwartz

179k17 gold badges214 silver badges277 bronze badges

4

C does not know where is the end of your dynamic array. you should remember the size that you allocate for the array.

answered Apr 19, 2012 at 2:35

Fei Xue's user avatar

Fei XueFei Xue

1,9855 gold badges19 silver badges29 bronze badges

when u allocate memory with malloc, the number of bytes allocated is stored just before the start of the ‘malloc’ated memory. if you know the size, you know the end as well!
This is explained in the bible of C, the K&R book. Wish I could give you the page number as well, but you’ll know it when u see it.

answered Apr 19, 2012 at 5:41

Sriharsha's user avatar

is the constant integer 5 will be stored some where?

Yes, it’s part of the type of the array. But no, it’s not stored anywhere explicitly. When you have

int i[5] = { };

the type of i is int[5]. Shafik’s answer talks about how this length is used to implement end.

If you’ve C++11, using constexpr would be the simple way to go

template <typename T, size_t N>
inline constexpr size_t
arrLen(const T (&arr) [N]) {
    return N;
}

If you’ve a pre-C++11 compiler where constexpr isn’t available, the above function may not be evaluated at compile-time. So in such situations, you may use this:

template <typename T, size_t N>
char (&arrLenFn(const T (&arr) [N]))[N];

#define arrLen(arr) sizeof(arrLenFn(arr))

First we declare a function returning a reference to an array of N chars i.e. sizeof this function would now be the length of the array. Then we’ve a macro to wrap it, so that it’s readable at the caller’s end.

Note: Two arrays of the same base type but with different lengths are still two completely different types. int[3] is not the same as int[2]. Array decay, however, would get you an int* in both cases. Read How do I use arrays in C++? if you want to know more.

(PHP 4, PHP 5, PHP 7, PHP 8)

endSet the internal pointer of an array to its last element

Description

end(array|object &$array): mixed

Parameters

array

The array. This array is passed by reference because it is modified by
the function. This means you must pass it a real variable and not
a function returning an array because only actual variables may be
passed by reference.

Return Values

Returns the value of the last element or false for empty array.

Changelog

Version Description
8.1.0 Calling this function on objects is deprecated.
Either convert the object to an array using get_mangled_object_vars() first, or use the methods
provided by a class that implements Iterator, such as ArrayIterator, instead.
7.4.0 Instances of SPL classes are now treated like empty objects that have no properties instead of calling the Iterator method with the same name as this function.

Examples

Example #1 end() example


<?php

$fruits

= array('apple', 'banana', 'cranberry');
echo
end($fruits); // cranberry?>

See Also

  • current() — Return the current element in an array
  • each() — Return the current key and value pair from an array and advance the array cursor
  • prev() — Rewind the internal array pointer
  • reset() — Set the internal pointer of an array to its first element
  • next() — Advance the internal pointer of an array
  • array_key_last() — Gets the last key of an array

franz at develophp dot org

12 years ago


It's interesting to note that when creating an array with numeric keys in no particular order, end() will still only return the value that was the last one to be created. So, if you have something like this:

    <?php

    $a
= array();

   
$a[1] = 1;

   
$a[0] = 0;

    echo
end($a);

   
?>



This will print "0".


jasper at jtey dot com

16 years ago


This function returns the value at the end of the array, but you may sometimes be interested in the key at the end of the array, particularly when working with non integer indexed arrays:

<?php
// Returns the key at the end of the array
function endKey($array){
end($array);
return
key($array);
}
?>

Usage example:
<?php
$a
= array("one" => "apple", "two" => "orange", "three" => "pear");
echo
endKey($a); // will output "three"
?>


jorge at REMOVETHIS-2upmedia dot com

11 years ago


If all you want is the last item of the array without affecting the internal array pointer just do the following:

<?phpfunction endc( $array ) { return end( $array ); }$items = array( 'one', 'two', 'three' );
$lastItem = endc( $items ); // three
$current = current( $items ); // one
?>

This works because the parameter to the function is being sent as a copy, not as a reference to the original variable.


Anonymous

20 years ago


If you need to get a reference on the first or last element of an array, use these functions because reset() and end() only return you a copy that you cannot dereference directly:

<?php

function first(&$array) {

if (!
is_array($array)) return &$array;

if (!
count($array)) return null;

reset($array);

return &
$array[key($array)];

}

function

last(&$array) {

if (!
is_array($array)) return &$array;

if (!
count($array)) return null;

end($array);

return &
$array[key($array)];

}

?>


ivijan dot stefan at gmail dot com

9 years ago


I found that the function end() is the best for finding extensions  on file name. This function cleans backslashes and takes the extension of a file.

<?php
private function extension($str){
   
$str=implode("",explode("\",$str));
   
$str=explode(".",$str);
   
$str=strtolower(end($str));
     return
$str;
}
// EXAMPLE:
$file='name-Of_soMe.File.txt';
echo
extension($file); // txt
?>

Very simple.


Jason

10 years ago


$filename = 'somefile.jpg';

php v5.4 does not support the following statement.
echo end(explode(".", $filename)); // return jpg string

instead you have to split into 2 statements
$file = explode(".", $filename);
echo end ($file);


ken at expitrans dot com

17 years ago


Please note that from version 5.0.4 ==> 5.0.5 that this function now takes an array. This will possibly break some code for instance:

<?phpecho ">> ".end(array_keys(array('x' => 'y')))."n";?>

which will return "Fatal error: Only variables can be passed by reference" in version <= 5.0.4 but not in 5.0.5.

If you run into this problem with nested function calls, then an easy workaround is to assign the result from array_keys (or whatever function) to an intermediary variable:

<?php

$x

= array_keys(array('x' => 'y'));
echo
">> ".end($x)."n";?>


Aleksandr

5 years ago


<?php
$A
=[1];
print_r($A);
end($A[5]);
print_r($A);
?>

Array
(
    [0] => 1
)
Array
(
    [0] => 1
    [5] =>
)

laurence at crazypillstudios dot com

12 years ago


this is a function to move items in an array up or down in the array. it is done by breaking the array into two separate arrays and then have a loop creates the final array adding the item we want to move when the counter is equal to the new position we established the array key, position and direction were passed via a query string

<?php

//parameters

//$array- the array you are modifying

//$keytomove - the key of the item you wish to move

//$pos - the current position of the item: used a count($array) function

//and then loop with incrementing integer to add the position to the up //or down button

//$dir - the direction you want to move it - "up"/"dn"
function change_pos($array, $keytomove, $pos, $dir){

   
//count the original number of rows

   
$count = count($array);

   
//set the integer we will use to place the moved item

   
if($dir=="up"){

        if(
$pos==1){

           
//if the item is already first and we try moving it up

            //we send it to the end of the array

           
$change = $count;

        }else{

           
//anywhere else it just moves back one closer to the start of the array

           
$change = $pos-1;

        }

    }

   
//do the same for the down button

   
if($dir=="dn"){

        if(
$pos==$count){

           
$change = 1;

        }else{

           
$change = $pos+1;

        }

    }       

   
//copy the element that you wish to move

   
$move = $array[$keytomove];   

   
//delete the original from the main array

   
unset($array[$keytomove]);   

   
//create an array of the names of the values we

    //are not moving

   
$preint = 1;

    foreach(
$array as $c){       

       
$notmoved["{$preint}"] = $c['name'];       

   
$preint++;

    }   

   
//loop through all the elements

   
$int = 1;

    while(
$int<=$count){   

       
//dynamically change the key of the unmoved item as we increment the counter

       
$notmovedkey = $notmoved["$int"];

       
//when the counter is equal to the position we want

        //to place the moved entry we pump it into a new array

       
if($int==$change){

           
$neworder["{$keytomove}"] = $move;

        }

       
//add all the other array items if the position number is not met and

        //resume adding them once the moved item is written

       
if($contkey!=""){

           
$neworder["{$notmovedkey}"] = $array["{$notmovedkey}"];           

        }

   
$int++;

    }

   
    return(

$neworder);

}

?>



This is not too elegant but it works.


Jacob

5 years ago


Attempting to get the value of a key from an empty array through end() will result in NULL instead of throwing an error or warning becuse end() on an empty array results in false:

<?php

$a

= ['a' => ['hello' => 'a1','world' => 'a2'],
     
'b' => ['hello' => 'b1','world' => 'b2'],
     
'c' => ['hello' => 'c1','world' => 'c2']
    ];
$b = [];var_dump(end($a)['hello']);
var_dump(end($b)['hello']);
var_dump(false['hello']);?>

Results in:

string(2) "c1"
NULL
NULL


Anonymous

20 years ago


When adding an element to an array, it may be interesting to know with which key it was added. Just adding an element does not change the current position in the array, so calling key() won't return the correct key value; you must first position at end() of the array:

<?php

function array_add(&$array, $value) {

$array[] = $value; // add an element

end($array); // important!

return key($array);

}

?>


Sam Yong — hellclanner at live dot com

13 years ago


Take note that end() does not recursively set your multiple dimension arrays' pointer to the end.

Take a look at the following:
<?php// create the array for testing
$a = array();
$i = 0;
while(
$i++ < 3){
$a[] = array(dechex(crc32(mt_rand())),dechex(crc32('lol'.mt_rand())));
}
// show the array tree
echo '<pre>';var_dump($a);// set the pointer of $a to the end
end($a);// get the current element of $a
var_dump(current($a));
// get the current element of the current element of $a
var_dump(current(current($a)));?>

You will notice that you probably get something like this:

array(3) {
  [0]=>
  array(2) {
    [0]=>
    string(8) "764d8d20"
    [1]=>
    string(8) "85ee186d"
  }
  [1]=>
  array(2) {
    [0]=>
    string(8) "c8c72466"
    [1]=>
    string(8) "a0fdccb2"
  }
  [2]=>
  array(2) {
    [0]=>
    string(8) "3463a31b"
    [1]=>
    string(8) "589f6b63"
  }
}

array(2) {
  [0]=>
  string(8) "3463a31b"
  [1]=>
  string(8) "589f6b63"
}

string(8) "3463a31b"

The array elements' pointer are still at the first one as current. So do take note.


Omolewa stephen

6 years ago


I found using pathinfo very useful in getting extension of  a file.
<? Php
  $filename = dictionary.txt;
   $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)) ;

echo $ext; // txt
?>


aaaaa976 at gmail dot com

4 years ago


To get the first element:

    // Get first item.
    foreach ($array as $item) {
        $first = $item;
        break;
    }
    // $first will have the first element.


goran

7 years ago


In case you need add separator at end

$numbers = array('1','2','3','4');
        foreach ($numbers as $number){
            echo $number;
            if (end($numbers) != $number){
                echo ', ';
            }
        }


Как определить конец массива?

obok

Любитель
Сообщения: 53
Зарегистрирован: 10 апр 2018, 20:16

Как определить конец массива?

Долго искал и не как не могу понять как на языке SCL понять что кончился массив, попробую пояснить:

например есть оператор цикла WHILE DO в котором параметр продолжения цикла выступает массив с индексом i -> X значение индекса меняется внутри цикла и точное количество итераций заранее не известно (так как массив X передается в в блок из другого источника в виде входящих данных) , но известно что как только «I» превысит количество значений в массиве нужно закончить цикл.
Как я понимаю должно быть что-то типа запись ПризнакКонецМассива(X), в VBA эта команда записывается как EOF(X) и она может принимать значения False/true

WHILE EOF(X) DO
….;
END_WHILE;

Так вот вопрос как это записать на SCL? Что бы получать признак конца массива ?

PS
По сути команда EOF() сообщает возможно ли получить данные из указанного элемента, если данные прочитать можно то TRUE, а если нет то False.


POV

Специалист
Сообщения: 127
Зарегистрирован: 04 авг 2016, 16:28
Откуда: Нижний Новгород

Re: Как опредеть конец массива?

Сообщение

POV » 17 окт 2018, 23:22

А в SCL можно описать именно массив неизвестной длины? Как?
И еще передать такой массив в FC или FB?
Есть еще типы POINTER и ANY — почитайте руководство — там длина передается и можно ее получить.


obok

Любитель
Сообщения: 53
Зарегистрирован: 10 апр 2018, 20:16

Re: Как опредеть конец массива?

Сообщение

obok » 18 окт 2018, 17:53

POV писал(а):А в SCL можно описать именно массив неизвестной длины? Как?
И еще передать такой массив в FC или FB?
Есть еще типы POINTER и ANY — почитайте руководство — там длина передается и можно ее получить.

Я немного о другом спрашиваю, речь о том как понять что кончился массив? или например указанной переменной не существует?
У меня на самом деле размер массива известен конечно но в дальнейшем измениться и не хочется потом вспоминать копаться в коде и менять все зависящие от этого параметры.


Михайло

Администратор
Сообщения: 4073
Зарегистрирован: 19 сен 2012, 19:16

Re: Как определить конец массива?

Сообщение

Михайло » 18 окт 2018, 18:07

Попробуйте такой код:

Код: Выделить всё

VariantPut(SRC := #array_tag,
           DST := #variant_tag);
#length:=CountOfElements(#variant_tag);

array_tag — массив Array[lo..hi] of Type
variant_tag — переменная типа вариант Variant
length — тип UDINT

А вообще проще при каждом изменении размера массива сохранять новую длину сразу в переменную length.


POV

Специалист
Сообщения: 127
Зарегистрирован: 04 авг 2016, 16:28
Откуда: Нижний Новгород

Re: Как определить конец массива?

Сообщение

POV » 19 окт 2018, 09:59

А секция констант в описании не спасет?
Количество элементов массива и все циклы до описанной константы — поменяли константу — рекомпилировали — все ОК?


petr2off

Любитель
Сообщения: 41
Зарегистрирован: 01 ноя 2018, 05:11

Re: Как определить конец массива?

Сообщение

petr2off » 15 ноя 2018, 16:08

В TIA портал есть специальные функции для определения нижней и верхней границы. Дома запускать не буду, это занятия не для слабонервных, а вот завтра на работе посмотрю, если интересно.


petr2off

Любитель
Сообщения: 41
Зарегистрирован: 01 ноя 2018, 05:11

Re: Как определить конец массива?

Сообщение

petr2off » 17 ноя 2018, 13:52

Единственно, что хочу предупредить. В 1200 это хрень работает плохо. Т.е. сами функции работают хорошо, и все хорошо определяют. Но если массив используется как параметр (тир array[*]) — то почему то обрабатывается только 1-й элемент массива.
В 1500 все работает хорошо и правильно.



Как определить конец динамического массива ?

От:

IvanZ

 
Дата:  16.02.05 12:02
Оценка:

Массив создан динамически. При создании число его элементов известно, но нет желения его запоминать, т.к. таких однотипных массивов создается очень много. В дальнейшем необходимо обращаться к элементам этих массивов. Так вот, можно-ли как нибудь определить, что массив уже закончился и мы залезли в другую область памяти или всетаки придется хранить число элементов для каждого массива ?


Re: Как определить конец динамического массива ?

От:

IvanZ

 
Дата:  16.02.05 12:04
Оценка:

Забыл сказать, что пишу я на Builder 5 C++


Re: Как определить конец динамического массива ?

От:

Glоbus

Украина

 
Дата:  16.02.05 12:28
Оценка:

+1

Здравствуйте, IvanZ, Вы писали:

IZ>Массив создан динамически. При создании число его элементов известно, но нет желения его запоминать, т.к. таких однотипных массивов создается очень много. В дальнейшем необходимо обращаться к элементам этих массивов. Так вот, можно-ли как нибудь определить, что массив уже закончился и мы залезли в другую область памяти или всетаки придется хранить число элементов для каждого массива ?

1. Размер придется хранить.
2. Ваще лучше намой взгляд вместо динамическог омасива пользовать std::vector — оччччень много головняка уходит.

Удачи тебе, браток!


Re: Как определить конец динамического массива ?

От:

Awaken

Украина

 
Дата:  16.02.05 12:42
Оценка:

>создается очень много. В дальнейшем необходимо обращаться к элементам этих массивов. Так вот, можно-ли как нибудь определить, что >массив >уже закончился и мы залезли в другую область памяти или всетаки придется хранить число элементов для каждого массива ?

можно с помощью системно-зависимых трюков например «сторожевых» участков памяти , при попытке записи куда происходит исключение
но нужно ли? используй готовые библиотеки контейнеров и не парься


Re[2]: Как определить конец динамического массива ?

От: Аноним

 
Дата:  16.02.05 12:46
Оценка:

Здравствуйте, IvanZ, Вы писали:

IZ>Забыл сказать, что пишу я на Builder 5 C++

std::vector спасёт отца русской демократии от лишнего геморроя


Re[2]: Как определить конец динамического массива ?

От:

sc

Россия

 
Дата:  16.02.05 13:37
Оценка:

-1

Здравствуйте, IvanZ, Вы писали:

IZ>Забыл сказать, что пишу я на Builder 5 C++

В С/C++ нет типа массив, а есть только указатель на память, в которой находятся однотипные данные. Поэтому узнать длину массива нельзя. Придется ее где-то хранить. А лучше использовать std::vector.


Re[2]: Как определить конец динамического массива ?

От:

IvanZ

 
Дата:  17.02.05 05:41
Оценка:

Всем спасибо


Re[3]: Как определить конец динамического массива ?

От:

Николай Ганичев

Россия

 
Дата:  17.02.05 07:03
Оценка:

Здравствуйте, sc, Вы писали:

sc>В С/C++ нет типа массив

В стандарте есть, а у вас — нет. Куда вдруг пропал?

sc>А лучше использовать std::vector.

Это точно.

… << RSDN@Home 1.1.4 @@subversion >>


Re: Как определить конец динамического массива ?

От:

Кодёнок

 
Дата:  17.02.05 13:30
Оценка:

IZ>Массив создан динамически. При создании число его элементов известно, но нет желения его запоминать, т.к. таких однотипных массивов создается очень много. В дальнейшем необходимо обращаться к элементам этих массивов. Так вот, можно-ли как нибудь определить, что массив уже закончился и мы залезли в другую область памяти или всетаки придется хранить число элементов для каждого массива ?

Есть (вдруг) ты имеешь ввиду динамический массив как в Delphi 7, с которым ты работаешь через SetLength(), то его длина уже хранится и её можно получить через Length() как и для строк.

Если выделяешь через malloc/new, то длину храни. Или std::vector.


Re[4]: Как определить конец динамического массива ?

От:

sc

Россия

 
Дата:  21.02.05 12:40
Оценка:

Здравствуйте, Николай Ганичев, Вы писали:

НГ>Здравствуйте, sc, Вы писали:


sc>>В С/C++ нет типа массив


НГ>В стандарте есть, а у вас — нет. Куда вдруг пропал?

Есть массивы, но нет типа массив, наподобие array of, как в Паскале. Или есть?


Re[5]: Как определить конец динамического массива ?

От:

Николай Ганичев

Россия

 
Дата:  21.02.05 14:32
Оценка:

Здравствуйте, sc, Вы писали:

sc>Есть массивы, но нет типа массив, наподобие array of, как в Паскале. Или есть?

Параграф 3.9.2 — Compound Types.

… << RSDN@Home 1.1.4 @@subversion >>


Re: Как определить конец динамического массива ?

От:

MAPCUAHUH

 
Дата:  22.02.05 14:06
Оценка:

Здравствуйте, IvanZ, Вы писали:

IZ>Массив создан динамически. При создании число его элементов известно, но нет желения его запоминать, т.к. таких однотипных массивов создается очень много. В дальнейшем необходимо обращаться к элементам этих массивов. Так вот, можно-ли как нибудь определить, что массив уже закончился и мы залезли в другую область памяти или всетаки придется хранить число элементов для каждого массива ?

Используй список а не динамический массив(проще вставлять удалять) список эффективнее. У последнего ссылка на следующий = NULL

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Понравилась статья? Поделить с друзьями:
  • Как найти складчатость на карте
  • Как найти модуль скорости движения по окружности
  • Задвоилось поступление как исправить
  • Как найти честного батюшку
  • Как найти все делители числа 496