I need to find the length of an array, how would I do this without using the sizeof function.
eg if
Array 1 = [0 1 2 3 4 5 6]
the size of this array would be 7.
If you can't use sizeof (tell us why, please), you can use a loop and a sentinel (-1 or some number that can not be used in the array):
int arr[] = {0, 1, 2, 3, 4, 5, 6, -1};
int count = 0;
while (arr[count] != -1) count++;
Many high-level programming language save the length of an array once it is created.
/* e.g. Java */
int[] foo = new int[10];
assert(foo.length == 10);
But the length of an array is not saved in C! This is useful as you can decide how you want to save the length with respect to optimization. You basically have three possibilities to get/save the length:
mark the end of the array with a certain value (i.e. \0 is used for strings)
char foo[] = "bar";
/* foo has length 4(sic!) as '\0' is automatically added to the end*/
int i = 0;
while(foo[i] != '\0'){
printf("%c",foo[i]);
i++;
}
save the length of the array in a variable
int foo[] = {1,2,3,4};
int length = 4;
for(int i = 0; i < length;i++){
printf("%i, ",foo[i]);
}
use sizeof (warning: sizeof is (mostly) computed at compile time and its use is restricted. you can only use sizeof within the function where the array has been created. when you pass an array to a function you only pass the pointer to the first element. therefore you can loop through this array as you know what offset must be used(type of its elements), but you do not know how big it is unless you also passed the length or added a sentinel value)
/* ok */
int foo[] = {1,2,3,4};
for(int i = 0; i < sizeof(foo)/sizeof(int);i++){
printf("%i, ",foo[i]);
}
/* not ok */
void foo(int bar[]);
void foo(int bar[]){
for(int i = 0; i < sizeof(bar)/sizeof(int);i++){
printf("%i, ",bar[i]);
}
}
int main()
{
int arr[] = {1,2,3,4};
foo(arr);
return 0;
}
Related
I have 2 questions.
First question is that, I'm trying to find the frequency of the sentence and put them into another array. However, the output of the new frequency nfreq is different from what is appended in for loop.
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main()
{
char str[] = "test sentence";
char nstr[] = "";
int freq[256] = {};
int nfreq[256] = {};
for(int i = 0; str[i] != '\0'; i++)
{
freq[str[i]]++;
}
printf("\nCharacter Frequency\n");
int j = 0;
for(int i = 0; i < sizeof(freq) / sizeof(int); i++)
{
if(freq[i] != 0)
{
printf("%5c%10d\n", i, freq[i]);
char c = i;
append(nstr, c);
int f = freq[i];
nfreq[j] = f;
printf("Num in nfreq[%d] is %d\n", j, nfreq[j]);
j++;
}
}
for(int i = 0; i < strlen(nstr); i++)
{
printf("%d ", nfreq[i]);
}
printf("\n");
printf("size of nfreq : %lu\n", sizeof(nfreq) / sizeof(nfreq[0]));
printf("size of str : %lu\n", strlen(str));
printf("size of nstr : %lu\n", strlen(nstr));
printf("nstr is : %s\n", nstr);
return 0;
}
The frequency of each letter is
Character Frequency
1
c 1
e 4
n 2
s 2
t 3
and nfreq should have those {1, 1, 4, 2, 2, 3} in its array with the code above and it even
says Num in nfreq[0] is 1 and etc in the loop, but when I try to check what's in nfreq outside the loop, it outputs {116, 1, 4, 2, 2, 3} this instead. What is this 116 and it should be 1 for the frequency of ' '.
Also the second question is that, if I were not to declare the size of an int array, int nfreq[] = {} like so in the beginning, does the size of this array, after appending int with for loop, changes dynamically? Or does it stay 0?
I tried fixing it by not declaring the size (which I don't think it matters) of nfreq array.
Thanks in advance for your help :)
Edit :
Sorry I forgot to add append function.
char nstr[] = "";
nstr is an array of one character.
append(nstr, c);
...
s[len+1] = '\0';
len is 0, so len + 1 is 1. This line is writing out-of-bounds to nstr. nstr is char [1]. You can only nstr[0] = something. nstr[1] is invalid.
Do:
char nstr[256] = "";
if I were not to declare the size of an int array, int nfreq[] = {} like so in the beginning, does the size of this array, after appending int with for loop, changes dynamically?
Notes: the {} is technically invalid, use {0} Is an empty initializer list valid C code? . int nfreq[] = {} is technically invalid code, it doesn't make sense, if it would, then nfreq would have zero size.
There are no "dynamic" changes of array size. Array has constant size. Writing out-of-bounds to an array is an error in the code.
Invalid initialization:
int freq[256] = {};
is invalid. ISO C forbids empty initializer braces. An initializer-list must contain at least one initializer.
Perhaps:
int freq[256] = { 0 };
Re:
if I were not to declare the size of an int array, int nfreq[] = {}
like so in the beginning, does the size of this array, after appending
int with for loop, changes dynamically? Or does it stay 0?
Answer: No.
int nfreq[] = {};
is not a valid statement. The space doesn't change dynamically.
Either declare an automatic array with fixed size like this:
int nfreq[SIZE] = { 0 };
or dynamically allocate memory with malloc(), and reallocate with realloc() as necessary.
Incorrect format specifier:
strlen() and sizeof() returns a type size_t. %lu might not be the correct format specifier for size_t. Use %zu instead.
See also:
Writing to out of bounds memory:
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
You didn't allocate any memory for the array that has decayed to a pointer in append(). So this writes to out of bounds memory, and exhibits undefined behaviour.
#include <stdio.h>
#include <stdlib.h>
int sumArray(int* p);
int main(){
int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, sum;
int* p = array;
sum = printf("The sum of the array is: %d", sumArray(p));
return 0;
}
int sumArray(int* p){
int sum = 0;
while(*p){
sum += *p;
p++;
}
return sum;
}
when i run this code i get a 6-digit value for sum, which looks more like an address. so what exactly am i doing wrong here?
while(*p) is a pretty idiomatic way of processing character strings in C because they have the useful property of being null-terminated. Once the null terminator (character with numeric value of 0) is reached, *p is 0 and the loop ends.
Your array does not have this property so while(*p) is true for the entire length of your array, then it goes out of bounds, which is undefined behavior.
Your options are:
Pass the size along with the array, and use int i = 0; while (i < LENGTH){} or more idiomatically for(int i = 0; i < LENGTH; i++)
Use a designated sentinel value to indicate the end of the array and use while (*p != SENTINEL)
Former option is the least hassle and doesn't require you to designate an arbitrary int as a magic number.
How can I move the last element of an array to the first element of another array if both of their sizes are 10. I need to remove the element from the first array and add it into the second array. And if the second array is full(has 10 elements) the element that was lost should be printed out like "Array 2 had no space, so element 5 was lost".
Code:
char arr[10] = {1,2,3,4,5};
char arr2[10] = {6,7,8,9,10};
result:
arr[10]={1,2,3,4};
arr2[10]={5,6,7,8,9,10};
If the arr2 is full:
char arr[10] = {1,2,3,4,5};
char arr2[10] = {6,7,8,9,10,11,12,13,19,20};
'''
result:
"Array 2 had no space, so element 5 was lost"
If you want to achieve exactly what you describe, you'll have to shift all the elements of the array. This has a time complexity of O(n) - which is why arrays are usually not very good for this kind of a job.
You also have to store the number of elements that are actually present in the array. Since there isn't exactly another way to know that unless you use a terminating element.
char arr[10] = {1,2,3,4,5};
char arr2[10] = {6,7,8,9,10};
size_t arrlen = 5;
size_t arr2len = 5;
if (sizeof(arr2) == arr2len)
{
printf("Element of value %d was lost\n", arr[arrlen - 1]);
return;
}
// Increase the length of arr2
arr2len++;
// Shift the elements
for (size_t i = arr2len - 1; i > 0; --i)
{
arr2[i] = arr2[i - 1];
}
// Set the new element
arr2[0] = arr[arrlen - 1];
// "Remove" the element from arr and decrement the length
arr[--arrlen] = 0;
Of course this is only a draft example - you should really really divide this into clean functions. Remember however, passing arrays to functions will decay them to pointers - in which case sizeof will not yield their full size, you'll have to pass that yourself.
Use a struct (containing the array) rather than the basic array.
struct arrayN {
int arr[10];
int N;
};
void last2first(struct arrayN *dst, struct arrayN *src) {
// NEEDS VALIDATION, for the moment we can say that
// it is UNDEFINED BEHAVIOUR calling last2first with bad data
memmove(dst->arr + 1, dst->arr, 9 * sizeof *dst->arr);
dst->arr[0] = src->arr[--src->N];
}
int main(void) {
struct arrayN arr1 = {{1, 2, 3, 4}, 4};
struct arrayN arr2 = {{42}, 1};
last2first(&arr1, &arr2);
}
Note: both arr1 and arr2 always have 10 elements in their array.
I'm learning C, and tried writing a function that, given an array of integer, returns the length of the array. Here is my code:
#include <stdio.h>
int length_of_array(int array[])
{
int length = 0;
int i = 0;
while (array[i] != '\0') {
length += 1;
i += 1;
}
return length;
}
int main()
{
int test_array[] = {1, 2, 3, 4, 5};
printf("%d\n", length_of_array(test_array));
return 0;
}
However, when I compile this code and run it, I says that the length of the array passed in is 14. Does anyone know what could be the problem here?
Strings in C are NUL-terminated. Arrays are not (unless you explicitly do it yourself). The size of array is just the size of array: if allocated as a constant, you can find out the size with sizeof operator. If all you have is a plain pointer, you need to remember the size - there is no way in C to get it once you forget it.
#include <stdio.h>
int main() {
int test_array[] = {1, 2, 3, 4, 5};
int *test_ptr = test_array;
printf("%lu\n", sizeof(test_array) / sizeof(*test_array)); // correct
printf("%lu\n", sizeof(test_ptr) / sizeof(*test_ptr)); // incorrect
return 0;
}
int a[10];
int b[10];
memcmp(a, b, sizeof(int) * 10);
memcmp() only tells us which memory block is bigger/smaller since it just returns -1,0,+1.
Is there a way to know number of matching elements in a[] and b[] just after which the mismatch occurs.
Ex: a = {1, 2, 3, 4, 5, 6}
b = {1, 2, 4}
Here memcmp(a, b, sizeof(int)* 3) would return -1. I want to get 2 as answer
Is there a way we can get number of matching elements with help of memcmp or some similar inbuilt function
I assume you want a low level answer since you must have already rejected the easy way with a loop.
You could XOR the memory block a[0] to a[9] with b[0] to b[9]. The resulting memory will be a block of zeros if, and only if, the original arrays were equal. To get the number of matching elements, count the number of int blocks that have all zero bits.
You could do this blisteringly fast in assembler as the operations are so simple.
A for loop over the two arrays should suffice:
int a[10];
int b[10];
int aLen = sizeof(a)/sizeof(int); /* we can do this since arrays are declared on the stack */
int bLen = sizeof(b)/sizeof(int);
int currentContig = 0;
int maxContig = 0;
for (int aIdx = 0, int bIdx = 0; (aIdx < aLen) && (bIdx < bLen); ) {
if (a[aIdx] == b[bIdx]) {
currentContig++;
aIdx++;
bIdx++;
}
else if (a[aIdx] > b[bIdx]) {
currentContig = 0;
aIdx++;
}
else {
currentContig = 0;
bIdx++;
}
if (currentContig > maxContig) {
maxContig = currentContig;
}
}
fprintf(stdout, "longest contiguous match: %d\n", maxContig);
Please Try Like below
int matched_num=0;
while(a[matched_num]==b[matched_num])
matched_num++;
printf("%d",matched_num);
final printed value will be total number of matched element in both arrays.