How to set every element in an array to 0 - c++

I am learning C++ and one of my practice exercises is to use pointers to set all the elements in an array to 0. I have no idea how to do this by incrementing the pointer to the next position in the array since my IDE log said that comparison between int and * is forbidden. I only need a small snippet as an example to help me better understand where i'm going wrong. The array I have created is of type int and has a single dimension with 5 elements consisting of 1,2,3,4 and 5.

int array[5] = {1, 2, 3, 4, 5};
for(int *i = &array[0], *end = &array[5]; i != end; i++)
*i = 0;
The code creates a pointer to the start &array[0] and a pointer to one position past the end &array[5]
Then it steps the pointer through the array, setting each element to zero.
A more advanced concept that is very similar is iterators.

You could use std::fill, http://en.cppreference.com/w/cpp/algorithm/fill, as follows.
const size_t dataSize = 10;
int data[dataSize];
std::fill(data, data + dataSize, 0);

Related

How to get intersection of two Arrays

I have two integer arrays
int A[] = {2, 4, 3, 5, 6, 7};
int B[] = {9, 2, 7, 6};
And i have to get intersection of these array.
i.e. output will be - 2,6,7
I am thinking to sove it by saving array A in a data strcture and then i want to compare all the element till size A or B and then i will get intersection.
Now i have a problem i need to first store the element of Array A in a container.
shall i follow like -
int size = sizeof(A)/sizeof(int);
To get the size but by doing this i will get size after that i want to access all the elemts too and store in a container.
Here i the code which i am using to find Intersection ->
#include"iostream"
using namespace std;
int A[] = {2, 4, 3, 5, 6, 7};
int B[] = {9, 2, 7, 6};
int main()
{
int sizeA = sizeof(A)/sizeof(int);
int sizeB = sizeof(B)/sizeof(int);
int big = (sizeA > sizeB) ? sizeA : sizeB;
int small = (sizeA > sizeB) ? sizeB : sizeA;
for (int i = 0; i <big ;++i)
{
for (int j = 0; j <small ; ++j)
{
if(A[i] == B[j])
{
cout<<"Element is -->"<<A[i]<<endl;
}
}
}
return 0;
}
Just use a hash table:
#include <unordered_set> // needs C++11 or TR1
// ...
unordered_set<int> setOfA(A, A + sizeA);
Then you can just check for every element in B, whether it's also in A:
for (int i = 0; i < sizeB; ++i) {
if (setOfA.find(B[i]) != setOfA.end()) {
cout << B[i] << endl;
}
}
Runtime is expected O(sizeA + sizeB).
You can sort the two arrays
sort(A, A+sizeA);
sort(B, B+sizeB);
and use a merge-like algorithm to find their intersection:
#include <vector>
...
std::vector<int> intersection;
int idA=0, idB=0;
while(idA < sizeA && idB < sizeB) {
if (A[idA] < B[idB]) idA ++;
else if (B[idB] < A[idA]) idB ++;
else { // => A[idA] = B[idB], we have a common element
intersection.push_back(A[idA]);
idA ++;
idB ++;
}
}
The time complexity of this part of the code is linear. However, due to the sorting of the arrays, the overall complexity becomes O(n * log n), where n = max(sizeA, sizeB).
The additional memory required for this algorithm is optimal (equal to the size of the intersection).
saving array A in a data strcture
Arrays are data structures; there's no need to save A into one.
i want to compare all the element till size A or B and then i will get intersection
This is extremely vague but isn't likely to yield the intersection; notice that you must examine every element in both A and B but "till size A or B" will ignore elements.
What approach i should follow to get size of an unkown size array and store it in a container??
It isn't possible to deal with arrays of unknown size in C unless they have some end-of-array sentinel that allows counting the number of elements (as is the case with NUL-terminated character arrays, commonly referred to in C as "strings"). However, the sizes of your arrays are known because their compile-time sizes are known. You can calculate the number of elements in such arrays with a macro:
#define ARRAY_ELEMENT_COUNT(a) (sizeof(a)/sizeof *(a))
...
int *ptr = new sizeof(A);
[Your question was originally tagged [C], and my comments below refer to that]
This isn't valid C -- new is a C++ keyword.
If you wanted to make copies of your arrays, you could simply do it with, e.g.,
int Acopy[ARRAY_ELEMENT_COUNT(A)];
memcpy(Acopy, A, sizeof A);
or, if for some reason you want to put the copy on the heap,
int* pa = malloc(sizeof A);
if (!pa) /* handle out-of-memory */
memcpy(pa, A, sizeof A);
/* After you're done using pa: */
free(pa);
[In C++ you would used new and delete]
However, there's no need to make copies of your arrays in order to find the intersection, unless you need to sort them (see below) but also need to preserve the original order.
There are a few ways to find the intersection of two arrays. If the values fall within the range of 0-63, you can use two unsigned longs and set the bits corresponding to the values in each array, then use & (bitwise "and") to find the intersection. If the values aren't in that range but the difference between the largest and smallest is < 64, you can use the same method but subtract the smallest value from each value to get the bit number. If the range is not that small but the number of distinct values is <= 64, you can maintain a lookup table (array, binary tree, hash table, etc.) that maps the values to bit numbers and a 64-element array that maps bit numbers back to values.
If your arrays may contain more than 64 distinct values, there are two effective approaches:
1) Sort each array and then compare them element by element to find the common values -- this algorithm resembles a merge sort.
2) Insert the elements of one array into a fast lookup table (hash table, balanced binary tree, etc.), and then look up each element of the other array in the lookup table.
Sort both arrays (e.g., qsort()) and then walk through both arrays one element at a time.
Where there is a match, add it to a third array, which is sized to match the larger of the two input arrays (your result array can be no larger than the largest of the two arrays). Use a negative or other "dummy" value as your terminator.
When walking through input arrays, where one value in the first array is larger than the other, move the index of the second array, and vice versa.
When you're done walking through both arrays, your third array has your answer, up to the terminator value.

Two- and one-dimensional arrays equivalence in C++

It is known that two- and one-dimensional arrays can be used equivalently, by simple coordinate conversion. Is such equivalence guaranteed by the C++ standard, or maybe it's the most convenient way of organizing data, but doesn't have to be obeyed everywhere?
For example, is the following code compiler-independent?
std::ofstream ofbStream;
ofbStream.open("File", std::ios::binary);
char Data[3][5];
for(int i=0; i<3; ++i)
for(int j=0; j<5; ++j)
{
Data[i][j] = (char) 5*i+j;
}
ofbStream.write(&Data[0][0], 15);
ofbStream.close();
The program is expected to write the numbers: 0, 1, 2, ..., 14 to a file.
In practice, this is just fine. Any compiler that doesn't do that would have countless problems with existing code.
Very strictly speaking, though, the pointer arithmetic needed is Undefined Behavior.
char Data[3][5];
char* p = &Data[0][0];
p + 7; // UB!
5.7/5 (emphasis mine):
When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that that difference of the subscripts of the resulting and original array elements equals the integral expression. ... If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.
The Standard does guarantee that all the array elements are adjacent in memory and are in a specific order, and that dereferencing a pointer with the correct address (no matter how you got it) refers to the object at that address, but it doesn't guarantee that p + 7 does anything predictable, since p and p + 7 don't point at elements of the same array or past-the-end. (Instead they point at elements of elements of the same array.)
In his book The C++ Programming Language, Bjarne Stroustrup mentions (C.7.2; p. 838 of the Special Edition, 2000):
... We can initialize ma like this:
void int_ma() {
for(int i=0; i<3; i++)
for(int j=0; j<5; j++) ma[i][j] = 10 * i + j; }
...
The array ma is simply 15 ints that we access as if it were 3
arrays of 5 ints. In particular, there is no single object in memory
that is the matrix ma - only the elements are stored. The dimensions 3
and 5 exist in the compiler source only.
(emphasis mine).
In other words, the notation [][]...[] is a compiler construction; syntactical sugar if you will.
For entertainment purposes, I wrote the following code:
#include<cstdlib>
#include<iostream>
#include<iterator>
#include<algorithm>
int main() {
double ma[5][3]; double *beg = &ma[0][0]; // case 1
//double ma[3][5]; double *beg = &ma[0][0]; // case 2
//double ma[15]; double *beg = &ma[0]; // case 3
double *end = beg + 15;
// fill array with random numbers
std::generate(beg, end, std::rand);
// display array contents
std::copy(beg, end, std::ostream_iterator<double>(std::cout, " "));
std::cout<<std::endl;
return 0;
}
And compared the assembly generated for the three cases using the compilation command (GCC 4.7.2):
g++ test.cpp -O3 -S -oc1.s
The cases are called c1.s, c2.s, and c3.s. The output of the command shasum *.s is:
5360e2438aebea682d88277da69c88a3f4af10f3 c1.s
5360e2438aebea682d88277da69c88a3f4af10f3 c2.s
5360e2438aebea682d88277da69c88a3f4af10f3 c3.s
Now, I must mention that the most natural construction seems to be the one-dimensional declaration of ma, that is: double ma[N], because then the initial position is simply ma, and the final position is simply ma + N (this is as opposed to taking the address of the first element of the array).
I find that the algorithms provided by the <algorithm> C++ Standard Library header fit much more snuggly in this case.
Finally, I must encourage you to consider using std::array or std::vector if at all possible.
Cheers.
C++ stores multi-dimensional arrays in row major order as a one-dimensional array extending through memory.
As other commenters have indicated, the 2-dimensional array will be mapped to 1-dimensional memory. Is your assumption platform independent? I would expect so, but you should always test it to be sure.
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
char Data[3][5];
int count = 0;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 5; ++j)
Data[i][j] = count++;
std::copy(&Data[0][0], &Data[0][0] + 15, std::ostream_iterator<int>(std::cout,", "));
}
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
http://www.fredosaurus.com/notes-cpp/arrayptr/23two-dim-array-memory-layout.html
How are multi-dimensional arrays formatted in memory?
Memory map for a 2D array in C
Quote
It follows from all this that arrays in C++ are stored row-wise (last subscript varies fastest) and that
the first subscript in the declaration helps determine the amount of storage consumed by an array but plays
no other part in subscript calculations.
C++ ISO standard

What is half open range and off the end value

What do these terminologies mean in C++?
1. off the end value
2. half open range - [begin, off_the_end)
I came across them while reading about for loops.
A half-open range is one which includes the first element, but excludes the last one.
The range [1,5) is half-open, and consists of the values 1, 2, 3 and 4.
"off the end" or "past the end" refers to the element just after the end of a sequence, and is special in that iterators are allowed to point to it (but you may not look at the actual value, because it doesn't exist)
For example, in the following code:
char arr[] = {'a', 'b', 'c', 'd'};
char* first = arr
char* last = arr + 4;
first now points to the first element of the array, while last points one past the end of the array. We are allowed to point one past the end of the array (but not two past), but we're not allowed to try to access the element at that position:
// legal, because first points to a member of the array
char firstChar = *first;
// illegal because last points *past* the end of the array
char lastChar = *last;
Our two pointers, first and last together define a range, of all the elements between them.
If it is a half open range, then it contains the element pointed to by first, and all the elements in between, but not the element pointed to by last (which is good, because it doesn't actually point to a valid element)
In C++, all the standard library algorithms operate on such half open ranges. For example, if I want to copy the entire array to some other location dest, I do this:
std::copy(first, last, dest)
A simple for-loop typically follows a similar pattern:
for (int i = 0; i < 4; ++i) {
// do something with arr[i]
}
This loop goes from 0 to 4, but it excludes the end value, so the range of indices covered is half-open, specifically [0, 4)
These aren't C++ specific terms, they are general maths terms.
[] and () denote whether the range is inclusive/exclusive of the endpoint:
[ includes the endpoint
( excludes the endpoint
[] = 'Closed', includes both endpoints
() = 'Open', excludes both endpoints
[) and (] are both 'half-open', and include only one endpoint
Most C++ for-loops cover a half-open range (you include the first element: e.g for int i=0;, but exclude the final element: i < foo, not i ≤ foo)
As explained on other answers, half-open range is also a mathematical term and usage of this term in programming context, it is implied that the starting point is included and end point is excluded.
What does it actually mean in the context of programming in C/C++ ? Let's say, you are going to print the elements of an integer array. Speaking for the C language, because that you have no any run-time knowledge for the size of the array, you have two choice. Either you have to provide the size of the array and thus, the function signature will be as below;
void printArray(int * array, int size);
or you have to use the half-open range, which means, you have to provide both begin and end pointer (and function is going to process including the begin, excluding the end) additional to the array itself. And the function signature will be as below;
void printArray(int * array, int * begin, int * end);
To illustrate, here is an example for providing the size of the array;
#include <stdio.h>
void printArray(int * array, int size)
{
printf("Array: ");
for(int i = 0; i < size; i++)
printf("%2d ", array[i]);
printf("\n");
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
printArray(array, 5);
return 0;
}
In the example above, we have passed two parameters to the printArray function as it is obvious on the function signature, the pointer to the first element of the array (or the array itself), and the size of the array.
However, as I have written above, we can also use the half-opening range in the function signature which can be seen as below;
#include <stdio.h>
void printArray(int * array, int * begin, int * end)
{
printf("Array: ");
for(int * index = begin; index != end; index++)
printf("%2d ", *index);
printf("\n");
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
printArray(array, array, array+5);
return 0;
}
Both of the code will produce the same output as can be seen below;
Array: 1 2 3 4 5
As you can see, the printArray function prints the function for the range [begin, end). The index which is actually is a pointer to the elements of the integer array, starts from begin, and it includes the begin and the for-loop ends up when index equals to the end pointer, excluding to process the end. This i called half-open range.
Half-open range is the C++ convention.

How does an index increment work in c++

My tutor told me to use an index to keep track of which character in the line the program is at. How does an index work exactly? I know its similar to count but other than that I am not sure.
At a high level, an index works on a collection. It simply says "I want the nth element of that collection" (where n is your index).
So if you have:
int foo[] = {2, 3, 5, 8, 13}; // array of 5 integers
Using 0 as the index will give you 2, using 1 will give you 3, using 2 will give you 5, using 3 will give you 8 and using 4 will give you 13.
All these are constant indices, so they will always give you the same result. However, if you use a variable as an index, that means you can retrieve a varying element from your collection.
In the case of an array, that collection is simply a block of contiguous memory. The array itself is a memory address, and by adding the index to that memory address, you find the element you're looking for.
By index he just means a pointer to the specific character. This can simply be an integer keeping track of the characters position or an actual pointer type.
string test = "Hello";
const int sLength = 5;
int index = 0;
for ( ; index < sLength ; index++ )
{
cout << "Character at index " << index << " = " << test[index];
}
In the beginning, it helped me to think of indexes as bookmarks. The bookmark keeps track of the last thing at which I was looking.
However, to really understand indexes, you should investigate pointers. You need to understand how structures are stored in memory, what addresses are, and how to sanely move from one address to another.

How to use pointers in for loops to count characters?

I was looking through the forums and saw a question about counting the numbers of each letter in a string. I am teaching myself and have done some research and am now starting to do projects. Here I have printed the elements of the array. But I do so without pointers. I know I can use a pointer to an array and have it increment for each value, but I need some help doing so.
Here is my code without the pointer:
code main() {
char alph [] = {'a', 'b', 'c'};
int i, o;
o = 0;
for(i=0; i < 3; i++)
{ cout << alph[i] << ' '; };
};
Here is my bad code that doesn't work trying to get the pointer to work.
main() {
char alph [] = {'a', 'b', 'c'};
char *p;
p = alph;
for (; p<=3; p++);
cout << *p;
return 0;
};
I hope that it's not too obvious of an answer; I don't mean to waste anyone's time. Also this is my first post so if anyone wants to give me advice, thank you.
Very good try. There's just one tiny thing wrong, which is this:
p <= 3
Pointers are just some number which represents a memory address. When you do p = alph, you're not setting p to 0, you're setting it to point to the same address as alph. When looping over an array with pointers, you have to compare the current pointer with a pointer that is one past the end of the array. To get a pointer to one element past the end of the array, you add the number of elements to the array:
alph + 3 // is a pointer to one past the end of the array
Then your loop becomes
for (; p < alph + 3; ++p)
You may think that getting a pointer to one past the end of the array is going out of bounds of the array. However, you're free to get a pointer to anywhere in memory, as long as you don't dereference it. Since the pointer alph + 3 is never dereferenced - you only use it as a marker for the end of the array - and everything is fine.
Here are some rough correlations for the different versions:
/-----------------------------------\
| Pointer Version | Index Version |
-------------------------------------
| p | i |
| p = alph | i = 0 |
| *p | alph[i] |
| alph + 3 | 3 |
| p < alph + 3 | i < 3 |
\-----------------------------------/
Also note that instead of doing alph + 3, you may want to use sizeof. sizeof gives you the number of bytes that an object occupies in memory. For arrays, it gives you the number of bytes the whole array takes up (but it doesn't work with pointers, so you can do it with alph but not with p, for example). The advantage of using sizeof to get the size of the array is that if you change the size later, you do not have to go and find all the places where you wrote alph + 3 and change them. You can do that like this:
for (; p < alph + sizeof(alph); ++p)
Additional note: because the size of char is defined to be 1 byte, this works. If you change the array to an array of int, for example (or any other type that is bigger than 1 byte) it will not work any more. To remedy this, you divide the total size in bytes of the array with the size of a single element:
for (; p < alph + sizeof(alph) / sizeof(*alph); ++p)
This may be a little complicated to understand, but all you're doing is taking the total number of bytes of the array and dividing it by the size of a single element to find the number of elements in the array. Note that you are adding the number of elements in the array, not the size in bytes of the array. This is a consequence of how pointer arithmetic works (C++ automatically multiplies the number you add to a pointer by the size of the type that the pointer points to).
For example, if you have
int alph[3];
Then sizeof(alph) == 12 because each int is 4 bytes big. sizeof(*alph) == 4 because *alph is the first element of the array. Then sizeof(alph) / sizeof(alph) is equal to 12 / 4 which is 3, which is the number of elements in the array. Then by doing
for (; p < alph + sizeof(alph) / sizeof(*alph); ++p)
that is equivalent to
for (; p < alph + 12 / 4; ++p)
which is the same as
for (; p < alph + 3; ++p)
Which is correct.
This has the good advantage that if you change the array size to 50 and change the type to short (or any other combination of type and array size), the code will still work correctly.
When you get more advanced (and hopefully understand arrays enough to stop using them...) then you will learn how to use std::end to do all this work for you:
for (; p < std::end(alph); ++p)
Or you can just use the range-based for loop introduced in C++11:
for (char c : alph)
Which is even easier. I recommend understanding pointers and pointer arithmetic well before reclining on the convenient tools of the Standard Library though.
Also good job SO, you properly syntax-highlighted my ASCII-Art-Chart.
The pointer loop should be:
for (char * p = alph; p != alph + 3; ++p)
{
std::cout << *p << std::endl;
}
You can get a bit more fancy by hoisting the end of the array out of the loop, and by inferring the array size automatically:
for (char * p = alph, * end = alph + sizeof(alph)/sizeof(alph[0]); p != end; ++p)
In C++11, you can do even better:
for (char c : alph) { std::cout << c << std::endl; }
Your problem (apart from compilation issues noted in my comment to the question) is that pointers are not as small as 3. You need:
for (p = alph; p < alph + sizeof(alph); p++)
for the loop. Note that sizeof() generates a compile-time constant. (In C99 or C2011, that is not always the case; in C++, it is always the case, AFAIK). In this context, sizeof() is a fancy way of writing 3, but if you add new characters to the array, it adjusts automatically, whereas if you write 3 and change things, you have to remember to change the 3 to the new value too.
Ruminations on the use of sizeof()
As Kerrek SB points out, sizeof() returns the size of an array in bytes. By definition, sizeof(char) == 1, so in this context, it was safe to use sizeof() on the array. There are also times when it is not safe - or you have to do some extra work. If you had an array of some other type, you can use:
SomeType array[] = { 2, 3, 5, 7, 11, 13 };
then the number of elements in the array is (sizeof(array)/sizeof(array[0])). That is, the number of elements is the total size of the array, in bytes, divided by the size of one element (also in bytes).
The other big gotcha is that if you 'pass an array' as a function argument, you can't use sizeof() on it to get the correct size - you get the size of a pointer instead. This is a good reason for not using C-style strings or C-style arrays: use std::string and std::vector<SomeType> instead, not least because you can find their actual size reliably with a member function call.
I recommand you the following revised code.
char alph [] = {'a', 'b', 'c', 0};
char *p;
p = alph;
while(*p)
{
std::cout << *p++;
}
0 marks the end of a string in both c and c++.