Confused regarding this statement about "function call by reference." - c++

What I'm confused about is whether the question is asking about passing arguments to functions as references (as opposed to "Call by Value") or about how we can set a pointer to point to a function.
The exact question is:
"Explain the function call by reference giving a suitable example in support of your answer."
The way it's termed makes it feel like it's asking about the latter. In my head, it seems as if it's asking how a function is called by reference, i.e, using a pointer.
C++ for what I'm talking about: int (*ptr)(int, int);
Which can later be assigned to a function like int max(int a, int b);
I know this is a bit of an odd post for Stack since it's more of an English question, but it's the only place I could think to ask.
EDIT: A lot of people are asking what I mean by the second thing. Since I'm new to the concept, I'll just copy - paste what my textbook gives as an example: (Sorry for the terrible formatting, sorry!)
main() {
int max(int a, int b){...}; //Your typical maximum function
int (*ptr)(int, int);
ptr = max;
//Then if you want to run the program
m = (*ptr)(2, 5);
cout << m; //Outputs 5
}

Related

why "return 0" works for returning a pointer in function, but not works for reference?

edit on Feb 25: changed my question, and adding some describes to my question.
======================some complains===========================
To those people who down-vote my question:
This is my first question on stack-overflow.
about the question: this question was emerged from my thought. in my case, I thought the return 0 actually did something for my
program, and it absolutely did. The only thing could misunderstand
people is probably I gave a question that I think it works like that
way but it didn't.
about my attitude. Maybe you guys here are expert in C++ and you might think my question is stupid. However, as a non-English-native speaker, this question is took me 4 hours to think and do the test, 2 hours for searching on google but also took me at least half hour to post. As a self-taught newbie I already tried my best to make the question as best as I could.
Thus, please at least leave a comment to let me know what I could improved about the way I submit my question, when you do the downvote. Do not just make a simple click. Your click is just like a new question to make me consider: "am i did something wrong?" "how could I solve it?" It is going to force me to reconsider what I’ve done; but just like the normal questions, It would be help if someone could give some tips.
As a newbie, I won't stop to raise questions; so I think point out my problems will help me to improve my ability to raise high quality questions, and you will benefit also because you might see some good questions in future.
At last, thanks again for this place; I got a lot answers from here; And also thanks for those people who helped me to solved my problem.
=======================question line======================
This function I intend to get an array argument by using "using alias form", and trying to return the array itself back to the calling function. I tried to use pointer and reference both for this function.
here is what I learned from C++ primer:
using arrT = int[10];
arrT* func(int i);
This code is suppose to define a function that would return a pointer that point to a array with ten ints; I understand this, but I didn't get a example from book.
and here are my tries:
using pointer, trying to return the pointer directly, but error.
arrT* return_p(arrT arr){
for(int i = 0; i < 10; ++i){
*(arr+i) *= 2;
}
return arr;//error, can't convert int* to int (*)[10]
}
i know because here arr is converted and lost the array's dimension. However, I just found a way that works for me:
arrT* return_p(arrT arr){
for(int i = 0; i < 10; ++i){
*(arr+i) *= 2;
}
return 0; // return 0 is return pointer arr that point the first element of array arr.
}
I just wondering how did the return 0 work here? And I do have another result here if I use reference instead of using pointer:
arrT& return_r(arrT &arr){
for(auto &i : arr){
i *= 2;
}
return arr; // works, returned the reference to array named arr
}
but return 0 is not working for the reference version.
arrT& return_r(arrT &arr){
for(auto &i : arr){
i *= 2;
}
return 0; // error, using an int rvalue to initialize a non_const that has type int(&)[10];
}
I hope I told my question clearly. thanks for your help!
The literal 0 is a "null pointer constant", and it can be used to initialize a value of any pointer type (object pointer, function pointer, member pointer or void pointer). The result of this initialization is the null pointer value of that type.
There is no concept corresponding to that of "null pointer" for references: references are always bound to objects or functions. For pointers the "null" value is in some way a distinguished value that says "not the address of anything". And by contrast, a reference is not allowed to not be bound to anything. That's why your last example is ill-formed.
Incidentally, you can return the address of an array if you pass the array as a reference:
arrT * f(arrT & a) { return &a; }
What's confusing about array types is that arrays cannot be passed to or returned from functions by value, but the corresponding syntax is allowed -- it is allowed, but means something different: f(arrT x) actually means the same as f(int * x) in your case.
In more technical terms, arrays can only be passed and returnd as and glvalues, but not as prvalues.

What is standard reference to lookup the scope of calls by reference?

First of all here is a snippet of some code that made me feel not quite sure about how reference identifiers work:
#include <iostream>
using namespace std;
void theUgly (int *z, int *q)
{
if(q == z)
*z=3;
/*else*/
*z=6;
};
void theNice (int &y, int *q)
{
theUgly(&y, q);
};
int main()
{
int x = 5;
theNice(x, &x);
cout << x << endl;
}
I wasn't sure to expect output be 3 or 5 since I wasn't sure about reference running with 2 identifiers having the 2 address, what seemed odd to me, or just leaving this handling to the user.
But I actually got 6 as output, what now lets me assume there is compiled in some kind of atomic operations.
I tried to find the exact documentation about this behavior in my "n3690" copy of the c++11 standard. I found the most part I was able to look up was dealing with capture reference declarations or other stuff named capture or lambda expressions. But just a handful of times I was able to strg+f "by reference" in it. And nothing really seemed to me like explaining the mechanic that describes the behaving of my snippet.
So my question simply is: Where exactly in the c++11 standard it is described, how a program has to handle the parameters and scopes, as happened for my test snippet?
EDIT:
After noticing and adding the missing else the snippet puts out what I would expect. But since I wasn't able to find any information about the behaving of passes by refference in the standard docs, The question remains as it is, independed of the snippet.
Your *z=6; is not in an else clause. This assignment is executed in any case.
Actually, g++-5.3 -O2 -std=c++14 transforms theNice into:
void theNice (int &y, int *q)
{
y = 6;
};
As for the behaviour of references as functions arguments:
[dcl.fct]: function parameter declaration
[dcl.init.ref]: initialization of references
[expr.call]: initialization of function parameters with argument expressions
In short: They behave like local references and reference (alias) the (l)value they are bound to. Calling a function which expects a (lvalue) reference with a (l)value binds that reference to the provided value in the scope of the callee.

Why doesn't this C++ function need return?

I saw some one write this code
int r, odd_divisors(int a, int b) {
r = sqrt(b) + 1;
r -= sqrt(a);
}
AFAIK, the compiler will automatically add return 0; at the end of this code, but in this case, it returns the value of r. Could someone please help me to explain why this happen. Thanks.
UPDATE:
This function actually works in this Codefights site: https://codefights.com/challenge/eu4zLJDcv88B2mcCp. You can check for sir_ementaler's solution.
UPDATE 2:
Thanks for everyone that pointed out this function is ill format. I knew that. The reason I asked here is because it is the winner's solution in the site I mentioned in the previous update. It looks to me that Codefights must add some other feature to their compiler.
The "implicit int" rule that you may know from pre-standard C does not apply to C++.
This is invalid code.
Fix your broken code.
The code you posted is not legal C++, but it is very close to legal. The following is legal:
// Example program
#include <iostream>
#include <string>
#include <math.h>
int r, odd_divisors(int a, int b);
int odd_divisors(int a, int b) {
r = sqrt(b) + 1;
r -= sqrt(a);
return 0;
}
int main()
{
odd_divisors(16,25);
std::cout << "Hello, " << r;
}
There are two things going on here. Firstly, you can define an int and declare a function in the same statement, but you can't define the function. Allowing this is an obvious compiler extension.
Secondly, failing to return a value from a value-returning function is undefined behaviour. That can mean a crash - but it can also mean doing exactly what you expect. If you don't try to use the value from the function, it is quite likely (but not certain), that nothing very much will happen.
It is of course, much cleaner to make odd_divisors be a void function, or better still, make it return the value and not use a static at all.

Changing the value of an attribute dynamically in cpp [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a struct :
struct Person{
int scoreone;
int scoretwo;
int scoretotal;
}
main(){
Person a;
a.scoreone=3;
a.scoretwo=5;
//and later
a.scoreone=10;
}
I want the scoretotal to be updated when scoreone and scoretwo are chnaged without using any function.
Thanks
That can't be done in C++. The C++ way to handle this is to convert scoretotal to a method
struct Person{
int scoreone;
int scoretwo;
int scoretotal() { return scoreone + scoretwo; }
};
Now instead of saying person.scoretotal you say person.scoretotal() and the score total will be recalculated each time.
Can't be done--to change a value automatically, you need to run some code, and (in either C or C++) code is always in a function.
The rest of this answer assumes the use of C++, and won't work in C at all.
You can, however, keep the fact that it's a function from being externally visible, which (I'd guess) is what you care about:
struct Person {
int scoreone;
int scoretwo;
class total {
int *a, *b;
public:
total(int *a, int *b) : a(a), b(b) {}
operator int() { return *a + *b; }
} scoretotal;
Person() : scoretotal(&scoreone, &scoretwo) {}
};
This does have a (usually minor) side effect. It depends upon an implicit conversion from Person::total to int to do its job. That can lead to unexpected results in a couple of situations. One would be if you're trying to use some_person.scoretotal in a situation where you expect an implicit conversion from int to some other type. You're already using an implicit conversion from Person::total to int, and the compiler will only use one user-defined conversion implicitly, that would fail. In the other direction, if you were to use auto x = some_person.scoretotal;, x would be a Person::total rather than an int, because auto would deduce the actual type without the implicit conversion happening.
As long as you do relatively obvious things like:
Person some_person;
some_person.scoreone = 1;
some_person.scoretwo = 2;
int total = some_person.scoretotal;
std::cout << "Total score: " << some_person.scoretotal;
...you'll get scoretotal tracking the total of scoreone and scoretwo without making it obvious that a function has to be invoked to do that.
Irrespective of the language that you are using, the fundamental problem is in the design of your struct. There are only two independent data values in this structure. But you are storing three. That is the mistake.
What you need to to is store just the two primary values, scoreone and scoretwo. Those are the data. The other value is a derived value defined by the relationship that the total is equal to the sum scoreone + scoretwo.
So you should remove the data member scoretotal and replace it with a function if you are coding in C, or a member function if you are coding in C++. In C the code might look like this:
struct Person{
int scoreone;
int scoretwo;
};
int scoretotal(const struct Person person)
{
return person.scoreone + person.scoretwo;
}
If you declare struct Person the way john did in his answer you should not get an error when calling the scoretotal function. Remember to include the parentheses, saying "person.scoretotal" won't work, you have to write "person.scoretotal()" because you're calling a function in the Person-struct, not asking for a member.

In a function declaration, what does passing a fixed size array signify? [duplicate]

This question already has answers here:
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
This feels like a really stupid thing to ask, but I had someone taking a programming class ask me for some help on an assignment and I see this in their code (no comments on the Hungarian notation please):
void read_dictionary( string ar_dictionary[25], int & dictionary_size ) {...
Which, as mainly a C# programmer (I learned about C and C++ in college) I didn't even know you could do. I was always told, and have read since that you're supposed to have
void read_dictionary( string ar_dictionary[], int ar_dictionary_size, int & dictionary_size ) {...
I'm told that the professor gave them this and that it works, so what does declaring a fixed size array like that even mean? C++ has no native way of knowing the size of an array being passed to it (even if I think that might've been changed in the newest spec)
In a one dimensional array It has no significance and is ignored by the compiler. In a two or more dimensional array It can be useful and is used by the function as a way to determine the row length of the matrix(or multi dimensional array). for example :
int 2dArr(int arr[][10]){
return arr[1][2];
}
this function would know the address of arr[1][2] according to the specified length, and also the compiler should not accept different sizes of arrays for this function -
int arr[30][30];
2dArr(arr);
is not allowed and would be a compiler error(g++) :
error: cannot convert int (*)[30] to int (*)[10]
The 25 in the parameter declaration is ignored by the compiler. It's the same as if you'd written string ar_dictionary[]. This is because a parameter declaration of array type is implicitly adjusted to a pointer to the element's type.
So the following three function declarations are equivalent:
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
void read_dictionary(string ar_dictionary[], int& dictionary_size)
void read_dictionary(string *ar_dictionary, int& dictionary_size)
Even in the case of the first function, with the size of the array explicitly declared, sizeof(ar_dictionary) will return the same value as sizeof(void*).
See this sample on Codepad:
#include <string>
#include <iostream>
using namespace std;
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
{
cout << sizeof(ar_dictionary) << endl;
cout << sizeof(void*) << endl;
}
int main()
{
string test[25];
int dictionary_size = 25;
read_dictionary(test, dictionary_size);
return 0;
}
Output (the exact value is, of course, implementation-dependent; this is purely for example purposes):
4
4
I always though that passing fixed size C++ arrays was a "half baked" feature of C++. For example, ignored size matching or only being able to specify the first index size, etc... Until recently I learn this idiom:
template<size_t N1, size_t N2> // enable_if magic can be added as well
function(double(&m)[N1][N2]){
... do something with array m...knowing its size!
}
Reference: Can someone explain this template code that gives me the size of an array?