Why is value only changed when referenced as calling argument? - reference

In this code:
#include <iostream>
int num1 = 0;
using namespace std;
void add(int &number);
int main()
{
int num2;
int num3;
add(num1);
cout << "Num1 is: " << num1 << ". Yep, " << num1 << ".";
}
void add(int &number)
{
number++;
}
The passed value "num1" to "add" will change it, but in this code:
#include <iostream>
int num1 = 0;
using namespace std;
void add(int number);
int main()
{
int num2;
int num3;
add(num1);
cout << "Num1 is: " << num1 << ". Yep, " << num1 << ".";
}
void add(int number)
{
number++;
}
It does not change, the value of "num1". Why is that?

In the second case, you increment a COPY of the paramter. In the first case, with the "reference", you modify the variable itself.
Look up "pass by value vs pass by reference. For example:
Pass by reference
Call by value
It should be noted that C (unlike C++) is always "pass by value" ... but the equivalent can be achieved by passing a pointer to a variable.

In the first case number is a reference to num1. That is that number is reference to the same place in memory num1 refers to. Similar to a pointer but without the hassle of dereferencing it.
In the second number is created in the activation record of add, and placed on the stack. When add terminates the number variable is poped off (and the memory of number is deallocated) the stack, and num1 is left unchanged in main's stack and activation record.
If it were an object and not a primitive, this could be seen in the debugger by where the segfault would occur if you were to manually called the destructor just before add returned.

Related

Why doesn't string class take in two words separated with space?

I want to take in persons name using string object. But in my code if I put two part name separated with a space, only first part is displayed. My understanding is .c_str() returns a pointer to stored string with terminal null. Why is there a problem with space. I'm new to C++ and using Code::Blocks 13.12. This is a simplified version of the problem that I have in another program that I wrote.
Thanks in advance.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
string sCusName;
cout << "Please enter your name-> ";
cin >> sCusName;
int xsize = sCusName.length();
char *tempBuffer = new char[xsize+1];
strncpy(tempBuffer, sCusName.c_str(),xsize+1);
cout << tempBuffer << " is a beautiful name." << endl;
return 0;
}
When I enter single part name, program works fine. But if I put in two part name separated with space. Only first part is taken in.
it is not possible to read multi-word string using cin rather you should use getline() the getline() function takes two arguments cin and string variable forexample:
int main()
{
string sCusName;
cout << "Please enter your name-> ";
getline(cin,sCusName);
cout << sCusName << " is a beautiful name." << endl;
return 0;
}

How to make an array of pointers and make the user enter the size of it?

I want to make an array, and inside this array there are pointers, like this:
int *arrp[size]; and I want the user to enter the size of it.
I tried to do this:
#include <iostream>
using namespace std;
int main ()
{
int size;
cout << "Enter the size of the array of pointers" << endl;
cin >> size;
int *arrp[size];
return 0;
}
but this doesn't work.
I also tried to do this:
#include <iostream>
using namespace std;
int main ()
{
int size;
cout << "Enter the size of the array of pointers" << endl;
cin >> size;
int* arrp[] = new int[size];
return 0;
}
also doesn't work, can someone help?
The error of the first code is that the size must be constant, I tried to fix that by writing the 2nd code but it gives an error for the word "new" in line 9:
E0520 initialization with '{...}' expected for aggregate object
and another error for the size in the same line:
C2440 'initializing': cannot convert from 'int *' to 'int *[]'
To make an array of pointers you should type: int** arr = new int*[size]
we type 2 stars '*', the first mean a pointer to an integer, the second means a pointer to the pointer to the integer, and then we make a place in the memory for those pointers by typing = new int*[size], you can use this as a 2D array that stored in the heap (not the stack) go to this website to know the difference: https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/.
to know more about how to use an array of pointers to a pointer to an integers you can see this video: https://www.youtube.com/watch?v=gNgUMA_Ur0U&ab_channel=TheCherno.

Convert string with 6 digits before decimal to Double

I have a string with the value 788597.31 and I am converting this value to double but when I print the variable only 788597 is displayed. I have used std::stod(string) and even stringstream but everytime I get the same previous value. Can anybody help me with this?
I want to store this string value in a double varaible.
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main()
{
string s="788597.31";
double d=stod(s);
cout<<d<<" ";
stringstream g;
double a;
g<<s; g>>a;
cout<<a;
return 0;
}
The problem is in how you are printing your result, not in the string parsing. This program:
#include <iostream>
using namespace std;
int main() {
cout << 788597.31 << endl;
return 0;
}
also prints 788597.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(10) << 788597.31 << endl;
return 0;
}
prints 788597.31
If you want to see more than the default 6 significant digits your program needs to say so.

How to scan strings with spaces in cpp in a new line?

enter image description here3(no of cases)
hello world
a b c d
data structures and algorithms.
Let say above is the given input format.Each string starts in a new line.Can i know how to read in the above way in cpp.I tried with getline function.It didn't work.
The getline method should work just fine. The following code works fine.
#include <iostream>
using namespace std;
int main(){
string s[3];
getline(cin, s[0]);
getline(cin, s[1]);
getline(cin, s[2]);
cout << s[0] << endl << s[1] << endl << s[2];
return 0;
}
EDIT:
After your clarification, it seems that the problem is actually that the buffer is not being cleared properly. So just use cin.ignore(); after cin >> t;
Refer to the code below:
#include <iostream>
using namespace std;
int main(){
int t;
cin >>t;
cin.ignore(); // This should clear the input buffer
string s;
getline(cin, s);
cout << s << endl;
return 0;
}

Reading a value in associative array creates a new key

I have code such as this. I use
pvalueholder is class that is polymorphic , it can hold all sort of types, string..etc..
It also can have a type undefined.
typedef hash_map<pvalueholder,pvalueholder,pvaluehasher > hashtype;
hashtype h;
pvalueholder v;
v="c";
h[v]=5; // h has one element
pvalueholder v2=h[v]; // here h gets a new key/value how is that possible?
cout << (string) (h[v]) << endl; // here h gets another new key/value how is that possible?
int i =0;
for (hashtype::iterator h1=h.begin(); h1!=h.end();h1++)
{
cout << "no: " << i++ << endl;
} // this prints three lines, it should print one...
Two values are undefined here, the third one is 5 as expected.
size_t pvaluehasher::operator() (const pvalueholder& p) const
{
cout << "hashvalue:" << p.value->hashvalue() << endl;
return p.value->hashvalue();
}
returns
Here is what is printed:
hashvalue:84696444
hashvalue:84696444
hashvalue:84696444
returns:1
hashvalue:84696444
returns:1
hashvalue:84696444
returns:1
returns:1
hashvalue:84696444
Do you have any ideas what it may be?
Thank you.
Solution:
the function operator()(parameter1,parameter2) needs to be different in case of Microsoft STL.
For microsoft, it needs to return less than relationship between parameter1 and parameter2.
For gcc, it needs to return equality. I returned equality.
The comparison function for the keys was not correct...
The function returned true for equality while it has to return less than in case of Microsoft STL.
My guess would be that your hash function is incorrect - meaning it produces different hash values given the same key "c".
Show the declaration for pvalueholder and full code for pvaluehasher.
It's almost impossible to comment on hash_map, because it's never been standardized, and the existing implementations aren't entirely consistent. Worse, your code doesn't seem to be correct or compilable as it stands -- some places the value associated with the key seems to be an int, and other places a string.
Using std::tr1::unordered_map and fixing the rest of the code to compile and seem reasonable, like this:
#include <unordered_map>
#include <iostream>
#include <string>
using namespace std;
typedef std::tr1::unordered_map<std::string, int> hashtype;
std::ostream &operator<<(std::ostream &os, std::pair<std::string, int> const &d) {
return os << d.first << ": " << d.second;
}
int main() {
hashtype h;
std::string v = "c";
h[v]=5; // h has one element
int v2=h[v];
cout << h[v] << endl;
int i =0;
for (hashtype::iterator h1=h.begin(); h1!=h.end();h1++)
{
cout << *h1 << endl;
} // this prints three lines, it should print one...
return 0;
}
The output I get is:
5
c: 5
This seems quite reasonable -- we've inserted only one item, as expected.
Solution: the function operator()(parameter1,parameter2) needs to be different in case of Microsoft STL. For microsoft, it needs to return less than relationship between parameter1 and parameter2. For gcc, it needs to return equality. I returned equality. The comparison function for the keys was not correct... The function returned true for equality while it has to return less than in case of Microsoft STL.

Resources