I want to use avgs as a pointer, but how would I modify the code below to use it correctly? I am computing the average of an int array, given the starting pointer and the length..
int compute_average(int *avgs, int len) {
int sum = 0;
for (int i = 0; i < len; i++)
sum += avgs[i];
return (int)(sum / len);
}
I tried writing it like this, but it didn't work correctly:
do {sum += *avgs;}
while(*(avgs++)!='\0');
Testing that your pointer doesn't point into a \0 is fine when you work with strings. Here you have an array of ints and a length so you can't really use a destination point to stop incrementing the pointer. You need to use that len just like in your first snippet but instead of accessing the ith element of your array, you can still increment the pointer. Something like this :
int compute_average(int *avgs, int len) {
int sum = 0;
for (int i = 0; i < len; i++)
sum += *(avgs++);
return (int)(sum / len);
}
Related
I want to create an array with the values from 0 to 4000 by increments of 100 and add those to an array.
I don't have much of as to how to do it.
int wave[] = {};
for(int i = 0; i < 4000; i = i + 100){
//add to wave[] i
}
Any help would be appreciated
Since you can use C++, the default option for storing an array of integers is std::vector:
std::vector<int> wave;
for (int i = 0; i <= 4000; i += 100)
wave.push_back(i);
If you want to have a C array as the result (e.g. for compatibility with other code that uses such arrays), because you know the final size of your array in advance, you better mention the size in the array definition:
int wave[41];
int index = 0;
for (int value = 0; value <= 4000; value += 100)
wave[index++] = value;
If you didn't know the final size, and for some reason didn't want to use std::vector, you'd have to use dynamically-allocated arrays (with malloc or new[]).
int main()
{
int wave[4096/100 + 1];
for(int i = 0, j=0; i < 4096; i = i + 100, j++)
wave[j]= i;
}
Could someone explain to me why this for-loop only runs one time no matter what n is:
double CalcDist(unsigned int n, Point p, Point* s)
{
double sd[n];
for(int i = 0; i < n; i++)
{
sd[i] = s[i].Dist_To(p);
return sd[i];
}
}
Thanks in advance for any help.
return exits the function prematurely, and is within the body of the for loop.
Also, be very careful when mixing unsigned and signed types when using expressions like i < n. Do you know off hand what would happen if n was 0?
If your aim is to determine the distance between one point to each point in an array, it goes like this :
double * CalcDist(unsigned int n, Point p, Point* pointsArray) {
double * result = new double[n]; //Iso C++ forbids veriable length array
//so don't use result[i] but this instead
for (unsigned int i = 0; i < n; i++) { //set i as an unsigned int as n is one
result[i] = pointsArray[i].Dist_To(p);
}
return result;
}
I'm trying to convert an 8 bit array into into a number from 0-255 by adding values depending on the position in the field.
if I use
int array[8]={
0,1,1,0,0,0,0,1
};
int *p = array;
int i;
for (i = 0; i<8; i++){
if(p[i]!=0){
a = pow(2,i);
printf("%i\n",a);
}
};
I get:
2
4
128
as results, which would be right so far.
but if I use
int array[8]={
0,1,1,0,0,0,0,1
};
int *p = array;
int i;
for (i = 0; i<8; i++){
if(p[i]!=0){
a = a + pow(2,i);
printf("%i\n",a);
}
};
I instead get:
2686758
2686762
2686890
when I expect:
134
What am I doing wrong?
You have not initialised a to 0.
The following should work
int array[8]={
0,1,1,0,0,0,0,1
};
int *p = array;
int i;
a = 0 // << Initialise a
for (i = 0; i<8; i++){
if(p[i]!=0){
a = a + pow(2,i);
printf("%i\n",a);
}
};
You always need to provide an initial value for your variables. Otherwise, you can expect them to start with ANY value.
In the second piece of code you are accumulating a=a+pow(2,i) and it is here where the first time a is used, it will contain some undetermined value.
The problem is in the statement: a = a + pow(2,1);
a has indeterminate value because it has not been initialized and you are using it in arithmetic operation.
pow is intended to compute the exponential function of two real (not integer) values. So you could use it to compute π3/2. It is really not ideal for computing integer powers of 2. Much simpler and faster (though possibly less readable until you get used to it) is to write 2i as (1UL << i). However, in this particular case you don't need either of those. You could just do the following:
int a = 0;
for (int index = 0, value = 1; index < 8; ++index, value *= 2)
if (p[i]) a += value;
or even more directly
int a = 0;
for (int value = 1, *p = array; value < 256; value *= 2, ++p)
if (*p) a += value;
(As has been mentioned, the problem in your original was not actually the use of pow but rather the absence of the initialization int a = 0.)
alright ! i fixed it by adding =0; to the int a;intitialization
Tanks !
I have this function
void shuffle_array(int* array, const int size){
/* given an array of size size, this is going to randomly
* attribute a number from 0 to size-1 to each of the
* array's elements; the numbers don't repeat */
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
r = mt_lrand() % size; // my RNG function
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
array[i] = r;
else
i--;
}
}
When I call this function from
int array[FIXED_SIZE];
shuffle_array(array, FIXED_SIZE);
everything goes all right and I can check the shuffling was according to expected, in a reasonable amount of time -- after all, it's not that big of an array (< 1000 elements).
However, when I call the function from
int *array = new int[dynamic_size];
shuffle_array(array, dynamic_size);
[...]
delete array;
the function loops forever for no apparent reason. I have checked it with debugging tools, and I can't say tell where the failure would be (in part due to my algorithm's reliance on random numbers).
The thing is, it doesn't work... I have tried passing the array as int*& array, I have tried using std::vector<int>&, I have tried to use random_shuffle (but the result for the big project didn't please me).
Why does this behavior happen, and what can I do to solve it?
Your issue is that array is uninitialized in your first example. If you are using Visual Studio debug mode, Each entry in array will be set to all 0xCC (for "created"). This is masking your actual problem (see below).
When you use new int[dynamic_size] the array is initialized to zeros. This then causes your actual bug.
Your actual bug is that you are trying to add a new item only when your array doesn't already contain that item and you are looking through the entire array each time, however if your last element of your array is a valid value already (like 0), your loop will never terminate as it always finds 0 in the array and has already used up all of the other numbers.
To fix this, change your algorithm to only look at the values that you have put in to the array (i.e. up to i).
Change
for(j = 0; j < size; j++)
to
for(j = 0; j < i; j++)
I am going to guess that the problem lies with the way the array is initialized and the line:
r = mt_lrand() % size; // my RNG function
If the dynamically allocated array has been initialized to 0 for some reason, your code will always get stack when filling up the last number of the array.
I can think of the following two ways to overcome that:
You make sure that you initialize array with numbers greater than or equal to size.
int *array = new int[dynamic_size];
for ( int i = 0; i < dynnamic_size; ++i )
array[i] = size;
shuffle_array(array, dynamic_size);
You can allows the random numbers to be between 1 and size instead of between 0 and size-1 in the loop. As a second step, you can subtract 1 from each element of the array.
void shuffle_array(int* array, const int size){
int i, j, r;
bool in_list;
for(i = 0; i < size; i++){
in_list = 0;
// Make r to be betwen 1 and size
r = rand() % size + 1;
for(j = 0; j < size; j++)
if(array[j] == r){
in_list = 1;
break;
}
if(!in_list)
{
array[i] = r;
}
else
i--;
}
// Now decrement the elements of array by 1.
for(i = 0; i < size; i++){
--array[i];
// Debugging output
std::cout << "array[" << i << "] = " << array[i] << std::endl;
}
}
You are mixing C code with C++ memory allocation routines of new and delete. Instead stick to pure C and use malloc/free directly.
int *array = malloc(dynamic_size * sizeof(int));
shuffle_array(array, dynamic_size);
[...]
free(array);
On a side note, if you are allocating an array using the new[] operator in C++, use the equivalent delete[] operator to properly free up the memory. Read more here - http://www.cplusplus.com/reference/new/operator%20new[]/
The function cannot initialize an array because sizeof() returns bytes of an int pointer
not the size the memory pointed by myArray.
void assignArray(int *myArray)
{
for(int k = 0; k < sizeof(myArray); ++k)
{
myArray[k] = k;
}
}
Are there other problems ?
Thanks
Well no, there are no other problems. The problem you stated is the only thing stopping you from initialising the array.
Typically, this is solved by simply passing the size along with the pointer:
void assignArray(int* myArray, std::size_t mySize)
{
for (std::size_t k = 0; k < mySize; ++k)
myArray[k] = k;
}
Note that I've used std::size_t for the size because that is the standard type for storing sizes (it will be 8 bytes of 64-bit machines, whereas int usually isn't).
In some cases, if the size is known statically, then you can use a template:
template <std::size_t Size>
void assignArray(int (&myArray)[Size])
{
for (std::size_t k = 0; k < Size; ++k)
myArray[k] = k;
}
However, this only works with arrays, not pointers to allocated arrays.
int array1[1000];
int* array2 = new int[1000];
assignArray(array1); // works
assignArray(array2); // error
I don't see other problems. However, you probably wanted this:
template<int sz>
void assignArray(int (&myArray)[sz])
{
for(int k = 0; k < sz; ++k)
{
myArray[k] = k;
}
}
Unless, of course, even the compiler doens't know how big it is at compile time. In which case you have to pass a size explicitly.
void assignArray(int* myArray, size_t sz)
{
for(int k = 0; k < sz; ++k)
{
myArray[k] = k;
}
}
If you don't know the size, you have a design error.
http://codepad.org/Sj2D6uWz
There are two types of arrays you should be able to distinguish. One looks like this:
type name[count];
This array is of type type[count] which is a different type for each count. Although it is convertable to type *, it is different. One difference is that sizeof(name) gives you count*sizeof(type)
The other type of array looks like this:
type *name;
Which is basically just a pointer that you could initialize with an array for example with malloc or new. The type of this variable is type * and as you can see, there are no count informations in the type. Therefore, sizeof(name) gives you the size of a pointer in your computer, for example 4 or 8 bytes.
Why are these two sizeofs different, you ask? Because sizeof is evaluated at compile time. Consider the following code:
int n;
cin >> n;
type *name = new type[n];
Now, when you say sizeof(name), the compiler can't know the possible future value of n. Therefore, it can't compute sizeof(name) as the real size of the array. Besides, the name pointer might not even point to an array!
What should you do, you ask? Simple. Keep the size of the array in a variable and drag it around where ever you take the array. So in your case it would be like this:
void assignArray(int *myArray, int size)
{
for(int k = 0; k < size; ++k)
{
myArray[k] = k;
}
}