This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
when do we need to pass the size of array as a parameter
So I just started working with arrays, I have 3 functions i need to create to get me to learn.
int sumarray(int a[], int n);
// a is an array of n elements
// sumarray must return the sum of the elements
// you may assume the result is in the range
// [-2^-31, 2^31-1]
int maxarraypos(int a[], int n);
// a is an array of n elements
// maxarraypos must return the position of
// the first occurrence of the maximum
// value in a
// if there is no such value, must return 0
bool lexlt(int a[], int n, int b[], int m);
// lexicographic "less than" between an array
// a of length n and an array b of length m
// returns true if a comes before b in
// lexicographic order; false otherwise
How exactly would I create these functions?
For sumarray, I'm confused since an array stores something within a certain length. Why would need the second parameter n?
And also how would I test a function that consumes an array? I was thinking like sumarray([3], 3) .. is that right?
When passed to a function, an array decays into a pointer, which inherently stores no length. The second argument would store the number of elements in the array, so, it would look something like this:
int values[] = { 16, 13, 78, 14, 91 };
int count = sizeof(values) / sizeof(*values);
printf("sum of values: %i\n", sumarray(values, count));
printf("maximum position: %i\n", maxarraypos(values, count));
for sumarray, im confused since an array stores something within a certain length, why would need the second parameter n?
You need the second parameter to tell you how long the array is. Arrays as parameters to methods in C don't come with their length attached to them. So if you have a method that takes an array as a parameter, it can't know the length unless you also pass that to the method. That's what n is for.
And also how would i test a function that consume's an array, i was thinking like sumarray([3], 3) .. is that right ?
No. You could say
int myArray[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
and then
int sum = sumarray(myArray, 10);
To solve all of these, you'll need loop (a for loop is best, I'm sure your lecturer provided examples on how to loop over the elements of an array). Beyond that, I'm not doing your homework. Ask specific, pointed questions, and I'd be happy to consider answering them though.
im confused since an array stores something within a certain length,
why would need the second parameter n?
Because you do not know the certain length. If you do not want to change the code when you change the length of the initial array, you need to pass around n because c language generally does not provide that information.
Related
So basically I have an array with a size of 5 and I want to count how many elements it has inside it.
int main()
{
int size;
char ola[5];
ola[0] = 'p';
size = sizeof(ola);
printf("%d\n", size);
return 0;
}
This code returns 5, but I expected 1.
What should I change?
The C standard does not provide any usable concept of elements in an array being used or unused. An array is simply a sequence of elements. It is up to you to track how many elements in it are of interest to you; you must write your own code for this.
You can do this by keeping a separate counter, by using a particular element value to denote that an element is “unused,” by using a particular element value to denote that an element ends the elements of interest, by calculating the end from related information, or by other means.
The C library includes many routines that use the third method, where the “null character,” with value zero, is used to mark the end of a string of characters. When you use this method, be sure to include room for the terminating null character in any array. For example, if you want an array to hold strings of length up to n characters, define the array to have at least n+1 elements.
Keep a count as you add elements to the array, rather than using sizeof (which returns the total capacity of the array in bytes), for example
#include <stdio.h>
int main(void)
{
int size = 0; // initialize size
char ola[5] = ""; // also initialize ola (with 5 '\0's)
ola[size++] = 'p'; // use and increment size
// size = sizeof(ola); // size is already updated
printf("%d\n", size);
// one more character
ola[size++] = 'o';
printf("%d\n", size);
printf("The string is [%s]\n", ola);
return 0;
}
It returns 5 because it is the size of your array, you could try:
size = sizeof(ola[0]);
To get the response 1, this mean that you are getteing exatly the size of the element, and not the size of whole array.
i only would know how to store value in the last position of the array, with the code below:
int main(int argc, char *argv[]){
int x[2][2];
int i, j;
x[2][0] = 1;
printf("%d", x[2][2]);
}
Thanks!
The last element in your matrix is in x[1][1]; just put in this position. Your vector has only four positions indexed starting in 0 going to 1 twice (for each dimension); that is, neither x[2][0] nor x[2][2] is valid — they access out of the bounds of the array.
The first element of an array in C is numbered as 0, and when creating an array, the size inputted will represent the number of elements in the said array. Hence, the first element of an array of 2 would be labelled as 0 and the second as 1, the third(2) not being allocated.
So, for example, making an array of 4 variables:
int i[4]
Would allocate four ints int memory,
i[0]
i[1]
i[2]
i[3]
these being the valid spots of the array. Of course this applies to 2D arrays like yours.
If you wish a 3-large array(Like I suppose from your use of the array element zero and two), you simply need to, as you probably understood, declare an array with a size of [3].
Keep in mind accessing invalid spots in an array might not cause a crash of your program if it had allocated some memory at the emplacement it tried to access, sometimes yielding to funny results caused by these unexpected values.
Hope this helps.
I have an array called allnumbersarray and I need to remove the duplicates of the array and store them in another called uniqueprimes. The allnumbersarray is composed of prime numbers. When I try to use an if - else if statement, the output gets jumbled and a lot of the elements turn to 0 and aren't sorted anymore. Here is what I've tried, not sure what to change:
int temp[], temp2[];
int removeDuplicates()
{
int n, j =0;
temp[n];
temp2[n];
// Start traversing elements
for (int i=0; i<n-1; i++){
// If current element is not equal
// to next element then store that
// current element
if (allnumbersarray[i] != allnumbersarray[i+1]){
temp[j++] = allnumbersarray[i];
}
else if(allnumbersarray[i] == allnumbersarray[i+1])
temp2[j++] = allnumbersarray[i];
}
// Store the last element as whether
// it is unique or repeated, it hasn't
// stored previously
temp[j++] = allnumbersarray[n-1];
// Modify original array
for (int i=0; i<j; i++){
allnumbersarray[i] = temp[i];
}
printf("\n\nprimes array with duplicates removed:\n");
for (int i = 0; i < j; i++)
printf("%d\n", allnumbersarray[i]);
return j;
}
You have not created an MCVE (Minimal, Complete, Verifiable Example — which is a problem. Some of the following criticism might be irrelevant if the code presented was an MCVE.
There are too many global variables in the code fragment (temp, temp2), and also not enough (you've not shown how allnumbersarray[] is defined). Use arguments to functions to pass data.
You say you have:
int temp[], temp2[];
int removeDuplicates()
{
int n, j =0;
temp[n];
temp2[n];
for (int i=0; i<n-1; i++){
You don't show where temp and temp2 are defined with a size — this line should have an extern in front of it. (I'm not sure why you don't use temp1 and temp2, but that's a common idiosyncrasy.)
The function isn't defined with a prototype; use int removeDuplicates(void) to indicate that it should be called with no arguments. As it stands, code in the same file could write removeDuplicates(3.14, "astronomy"); and the compiler is not obliged to spot the discrepancy because the function definition does not give a prototype for the function.
You have an uninitialized variable n inside the function; it's value is indeterminate. For some unexplained reason, you have temp[n]; and temp2[n];, statements which read from indeterminate locations in (or, more likely, outside) the dubiously declared arrays. The compiler might remove these references, if you're lucky, since they don't affect the computation. But they are misguided twice — once because they do nothing and once because they use the uninitialized variable to index the arrays.
You then use this uninitialized variable n as a bound for your main for loop. This is not going to end happily. You never use the values carefully stored in temp2.
I think you need to redesign your function thoroughly. For example, you might use:
int removeDuplicates(int *n_values, int *values, int *dups)
{
where *n_values is the number of entries in the source array (values), which becomes one of the output arrays. It's passed by reference so you can identify to the calling function how many unique entries there are in the values array after the duplicate removal is complete (use int n = *n_values; near the start, and *n_values = …new size…; at the end). The dups array is equivalent to your temp2. It is assumed to be 'big enough' (which is actually a dangerous assumption). The function will directly return the number of entries in dups, like the current function would if it were written correctly.
Somewhere along the line, with the current scheme, you have to copy the unique values from the source array (values) into spare space, simply so you can copy it back later. A better algorithm steps through the source array with two indexes, the current read position and the current write position. When you find an adjacent duplicate, you increment the read position without incrementing the write position. This means you end up not needing the temp array at all.
You also same the code 'removes duplicates' but the algorithm only looks for adjacent duplicates. If you had an input list (int[]){ 2, 3, 3, 5, 7, 7, 3, 11, 11, 13, 17, 19, 11 } (that's a compound literal), your code would not spot the third 3 nor the third 11. It isn't clear whether that's a problem — it may be that the duplicates can only occur adjacent to each other, in which case you don't have to be as complicated in your analysis as you do if duplicates need not be adjacent.
This at least gives you some things to think about.
Next time, please make sure you post a more complete MCVE; what you've presented is too minimal for comfort. And avoid global variables like the plague they are. Most functions should have parameters to identify what they're going to work on.
How can I determine the number of elements in an array of scanned in data?
For example, say I have an array that looks like this:
array[0,1,2,3,4,5,6,7,8,9];
Obviously I can count the number of elements in this array, but if I scan in a much larger array, I don't want to count the number of elements individually. How can I use code to find the number of elements?
You could use
int numberofelements = sizeof(array)/sizeof(int) //using type of array as int
However this cannot be done inside a function as the array is passed to it as a pointer so sizeof(array) will return size of the pointer.
Perform this calculation before calling any function
I'm trying to write a code for a function that gets an array (lets call it arr1) with values between 32 and 64, and the size of the array(lets say size n). The function will sort the array in O(n).
The way I thought of doing this is to declare a second array (lets call it arr2) with size of 32 and do this:
for every index i between 0 and n, we put 1 in arr2 in the spot [arr1[i]-32]. so that for example, if for the current i, arr1[i]=40, then we put 1 in arr2 in the spot 40-32, 8.
Then we iterate through arr2, and if arr2[i]==1 then in arr[j] i put i+32, j++. in theory, arr1 should now be sorted.
my problem is the code, i get a little red line below the "=" when assigning values to arr2, and when I hover over it, it says "value of type int can't be assigned to type int*"
void sort_array(int* arr1,int n)
{
int i=0,j=0;
int* arr2[32];
for(i=0;i<32;i++)
arr2[i]=0;
for(i=0;i<n;i++)
arr2[arr1[i]-32]=1;
for(i=0;i<32;i++)
if(arr2[i]==1)
{
arr1[j]=i+32;
j++;
}
}
I'd also like to hear if someone has a better suggestion on how to sort this array in O(n). quicksort and mergesort are nlog(n)
Thanks.
Here is the problem:
int* arr2[32];
This line should be
int arr2[32];
because arr2 contains counters, not pointers. That is why assigning 1 to elements of arr2 fails.
Now let's discuss your algorithm: your attempted implementation of counting sort will break for arrays with duplicate values, because you set arr2[arr1[i]-32] to 1 regardless of how many times you found an item. You should change it to arr2[arr1[i]-32]++, and use the count to put that many counted values into the resultant array. See pseudocode in the wikipedia article a the correct implementation.
Here is a table comparing performances of various sorting algorithms. Look for the second table with details on non-comparison sorts.
int *arr2[32];
should be
int arr2[32];
The former declares an array of 32 pointers.