C/C++

Strlen для int массивов.(Си)

Есть ли функция, которая определяет количество заполненных элементов int массива?
Не полное количество элементов в массиве, а количество существующих элементов нужно.
int arr[50]={1,2,3};
Здесь заполнено 3 элемента. Есть ли функция, которой можно получить это число 3 для int массива?
E /\
E /\
288
Нет такой функции. Напиши сам, делов-то (подобно strlen, считает до 0-терминатора):
АИ
Амiр Исмухамбетов
3 568
Лучший ответ
E /\ Я видел уже такую запись. Но не понимаю до конца как она работает.

Это для меня *num++;
То же самое что и это *num=num[0]+1;
Но оно почему то не так.

*num++; Так по логике должна прибавляться единица к первому элементу массива.

Но почему то между этим *num++; и этим num++; нет разницы.
E /\ --------------
https://onlinegdb.com/Rtt4xFz6b
int main()
{
int arr[50]={1,5,3};
int a=0;
int*num = arr;
while(num<arr+(sizeof(arr)/4))
{
printf("%d\n",num[0]);
num++; //Прибавляем к адресу + 4 Байта и переходим на следующий элемент массива
}
return 0;
}
-------------
https://onlinegdb.com/txUicH_On
int main()
{
int arr[50]={1,5,3};
int a=0;
int*num = arr;
while(num<arr+(sizeof(arr)/4))
{
printf("%d\n",num[0]);
*num++; //Здесь по логике должна инкрементироваться единица к первому элементу массива, но прибавляется так же 4 Байта к адресу.
}
return 0;
}
E /\ Кстати вот так
https://onlinegdb.com/Z8QQUgIAU
int main()
{
int arr[50]={1,5,3};
int a=0;
int*num = arr;
while(num[0]<100)
{
++*num;
printf("%d\n",num[0]);
}
return 0;
}
инкрементируется единица к первому элементу массива
E /\ Ок. Это я понял.
Но это нелогично ведь.

int*num = arr;

Это *num ссылается на ЗНАЧЕНИЕ нулевого элемента массива. Поэтому так *num++; должно инкрементироваться ЗНАЧЕНИЕ нулевого элемента массива.
То что оно по другому это понятно.

И ещё странное дело: мой компилятор пишет expression result unused напротив *num++; хотя дальше по коду это printf("%d\n",num[0]);
-------------
int main()
{
int arr[50]= { 1,5,3 } ;
int a=0;
int*num = arr;
while(num<arr+(sizeof(arr)/4))
{
*num++;
printf("%d\n",num[0]);
}
return 0;
}
E /\ Ай сори, кажется понял.
E /\ Оно не на значение ссылается, а на адрес значения
E /\ Блин ну если сделать так
int main()
{
int arr[50] = { 1,5,3 };
int a = 0;
int* num = arr;
printf("%p\n", *num);
return 0;
}
То компилятор попросит сменить спецификатор %p на %d
E /\ >>Я бы тоже попросил, если бы мне вместо указателя дали значение по указателю
Вот мои мысли.
*num; Это ЗНАЧЕНИЕ по адресу
num это адрес

Если значение инкрементировать, то должно инкрементироваться значение, а не адрес.

num++; Вот с этим вопросов нет. Инкрементируется адрес.
E /\ Возможно это просто типа удобный синтаксис языка.
E /\ Преоритет, да, точно. В этом могла бы быть причина.
E /\ Хитро и очень интересно))
E /\ Неприятность этого метода в том что при встрече с нулём в элементе массива, заканчивается подсчёт элементов *p++
Вы это и показали.
E /\ Я так сделал
https://onlinegdb.com/f0NJXP29c
Это не идеально конечно. Просто проверил.
С этим выражением *p++ помучался. Странно инкриментирует с этим условием
E /\ >>остальные элементы инициализируются нулями по умолчанию
Я просто наглядно показал что эти нули не считаются
>>a == n == 0 по умолчанию, поскольку переменные глобальные
В этом и задумка была. а-это тоже счётчик. Но счётчик, который читает элементы после того как встретится ноль.
>>Не стоит опускать void
int у функции есть, он выше в коде. Beautify я нажал, и так изменилось почему то.
>>Не стоит писать 4 вместо sizeof(int) или sizeof *arr
Почему так sizeof(*arr) не стоит писать? Первый элемент массива это как раз будет sizeof(int)
-----------------------
E /\ Эти глобальные переменные я сделал потому что через указатель я не мог узнать размер массива
int arr[50] = { 1, 5, 10, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 };
int *num = arr;
sizeof (num);//Так не работает. Возвращает инфо об указателе.
----------------------
E /\ >>Какой-то непонятный подсчет непонятно чего..
Считаю положительные элементы массива
while (num < arr + sizeof (arr) / 4)
{
if (num[0] > 0)
{
n++;
num++;
}
Когда встречается 0 среди элементов массива, я начинаю считать счётчиком а++;
else if (num[0] == 0)
{

num++;
a++;
Если псле нуля встречается положительное число в элементе массива, то я счётчик а++; присваиваю переменной n
n = a + n;

if (num[0] > 0)
{
++a;
n = a + n;
num++;
}
E /\ >>>>Не стоит писать 4 вместо sizeof(int) или sizeof *arr
А, это понял. Ок.
E /\ То же самое, но без глобальных переменных, как вы советовали
https://onlinegdb.com/hK7kDhF68
E /\ int func(int p[],int *end)
{
int a=0;
int n=0;

while(p<end)
{
if(p[0]==0)
{
while(p<end)
{
if(p[0]==0)
{
a++;
p++;
}
else
{
p++;
a++;
n=a+n;
}
}

}
else
{
p++;
n++;

}
}

return n;
}

int main()
{
int arr[50] = { 1, 5, 10, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 };
int *end=arr+_countof(arr);
printf("%d\n", func(arr, end));
}
E /\ Мой код выше неправильно работает если что))
Разбираюсь почему.
Можно вот так дело организовать.

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

#define RAND(min, max) (rand() % ((max) - (min)) + (min))

#define CAPACITY 50U
static size_t end = 0U;
int vector[CAPACITY];

_Bool empty() {
return end == 0U;
}
size_t length() {
return end;
}
_Bool push_back(int value) {
if (end == CAPACITY) return false;
vector[end] = value;
++end;
return true;
}
_Bool add_vector(int* vec, size_t len) {
size_t i;
for (auto i = 0; i < len; ++i) {
if (!push_back(vec[i])) break;
}
}
void pop_back() {
if (end) --end;
}
void show(size_t width) {
size_t i = 0U;
while (i != end) {
printf("%*i", width, vector[i]);
++i;
}
puts("");
}
void clear() {
end = 0U;
}

int main(void) {
int a[] = { 25, 37, 44, 21, 93, 37, 88, 20 };
int b[] = { -8, -2, -7, -3, -5, -1, -4, -9 };
const char* format = "Length: %zu\n";
srand((unsigned)time(NULL));
printf(format, length());
push_back(RAND(10, 26));
show(4U);
printf(format, length());
push_back(RAND(50, 100));
show(4U);
printf(format, length());
push_back(RAND(-9, 0));
show(4U);
printf(format, length());
push_back(RAND(15, 76));
show(4U);
printf(format, length());
while (!empty()) {
pop_back();
show(4U);
}
printf(format, length());
add_vector(a, _countof(a));
show(4U);
printf(format, length());
add_vector(b, _countof(b));
show(4U);
printf(format, length());
clear();
printf(format, length());
system("pause > nul");
}

P.S. Если свойство capacity также сделать статической переменной, а массив создавать динамически, то размер вектора можно изменять в процессе выполнения программы.
Максим Богдан
Максим Богдан
65 001
Такой функции нет. Т. к. нет критерия по которому массив считается заполненным или не заполненным.
Иван Чистяков Это не заполненность. Это подсчет элементов по какому-то фильтру. Сколько в массиве элементов больше нуля (меньше нуля, больше десяти, четных, делящихся на 5 без остатка, не входящих в список запрещенных... etc). То есть вы сами придумали фильтр и назвали его "заполненность массива".
В общем случае число 0 является полноправным членом int последовательностей.