Basic C array (I suck());

Hello, I have a C++ test tomorrow about a few basic things. One of them is using C arrays.

As a practice assignement I have to get the highest and lowest ASCII value from a given array:

char a[length] = { 'a', 'b', 't', 'a', 'z', 'Z', 'X' };

But I haven't gotten much further than this (I'm a noob). So what do I do now? :/ (also, the code doesn't work yet)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <iomanip>

using namespace std;

char determainHighestAndLowest(char *max, char *min, char a[], int length);


int main()
{
	const int length = 7;
	char max, min

	char a[length] = { 'a', 'b', 't', 'a', 'z', 'Z', 'X' };

	cout << "The maximum is: " << determainHighestAndLowest(&max, &min, a, length);

	cin.get();

}

char determainHighestAndLowest(char *max, char *min, char a[], int length)
{
	double max = a[0];
	double min = a[0];

	for (int i = 1; i < length; i++)
	{
		if (*max < a[i])
			*max = a[i];
	}


	for (int i = 1; i < length; i++)
	{
		if (*min > a[i])
			*min = a[i];
	}

}
That code has a lot of things right.

Just needs a bit of fixing here and there.

Line 12: missing semicolon.

Line 16. Don't try to call the function in the cout statement. Instead just call the function first, on a line by itself. Then use cout to output the values of max and min.

Lines 24 and 25. The mere presence of a variable of type double is enough to raise a few eyebrows. Also, the two variables declared have the same name as the two parameters max and min in the function header, and hence hide them.

Try this instead:
24
25
    *max = a[0];
    *min = a[0];


Lastly, the function determainHighestAndLowest() is declared as returning a value of type char, but it doesn't return anything. In fact it doesn't need to return anything. Just declare the function as type void.

Personally, I would have passed the variables max and min by reference rather than by pointer, since this is a C++ program.

See Arguments passed by value and by reference in the function tutorial:
http://www.cplusplus.com/doc/tutorial/functions/

You might also just use a single for loop inside the function body, there's no need to have two separate loops.
Hello Chervil, thank you for your anwser. The assignement was originally in Dutch and said:

"Create a function determainHighestAndLowestChar that searches an array and returns the highest and lowest ASCII value. Print this value in your main function."

I tried this step, but it messed things up even more.

Try this instead:
24
25
*max = a[0];
*min = a[0];


My classmates also mentioned call by reference, but I don't know how to apply it to this situation. I'm a bit lost now.
void foo(char * in); //one way to pass an array of characters into a function by reference is with a pointer (* symbol means pointer).

you can call this with
char array[100];
foo(array);

what this does is prevent copying 100 bytes to the function, and instead it operates on the same variable memory that was passed in, so if you modify "in" in the "foo" function you ALSO MODIFY array in your main program! That is critical to understand. It can be useful (don't need a return value, just do the work) or a bug (accidentally modify something you did not mean to change).

min and max are macro functions that many compilers define. Treat them as keywords and do not call a variable by this name. You can use them ... looks like maxval = max(maxval, otherval);

so you can do something like this, to put it all together... this is crude, and it uses the max and min macros, but it should give you an idea...

void maxmin(char *in, int length, char*out)
{
//defined: out[0] = min, out[1] = max
int i;
for(i = 0; i < length, i++)
{
out[0] = min(out[0], in[i]);
out[1] = max(out[1], in[i]);
}
}

main
{
...
char result[2];
cin >> input;
maxmin(input, strlen(input), result);
cout << "min:" << result[0] << endl; //etc

}

you would typically define constants for the offset int result to give it a meaningful name rather than the constant 0 and 1 but that is clutter for explaining this.

I tried this step, but it messed things up even more.
1
2
    *max = a[0];
    *min = a[0];

It's hard to understand how changing code that couldn't possibly work to something that might have some chance of working could be 'more messed up'.


Put in context it would look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void determainHighestAndLowest(char *max, char *min, char a[], int length)
{

    *max = a[0];
    *min = a[0];

    for (int i = 1; i < length; i++)
    {
        if (*max < a[i])
            *max = a[i];
    }


    for (int i = 1; i < length; i++)
    {
        if (*min > a[i])
            *min = a[i];
    }

}


And as I mentioned, change main too:
1
2
3
4
    determainHighestAndLowest(&max, &min, a, length);
    
    cout << "The maximum is: " << max << '\n';
    cout << "The minimum is: " << min << '\n';



My comments on the use of call by reference were an optional improvement you could make after first getting a working version of the program. Get it working first, then refine it afterwards.


Thank you for your answers, jonnin and Chervil.
With your suggestions I made this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <iomanip>

using namespace std;

char bepaalHoogsteEnLaagsteLetter(char *max, char *min, char a[], int lengte);


int main()
{
	const int lengte = 7;
	char min = 0;
	char max = 0;

	char a[lengte] = { 'a', 'b', 't', 'a', 'z', 'Z', 'X' };
	
	bepaalHoogsteEnLaagsteLetter(&max, &min, a, lengte);
	
	cout << max << endl;
	cout << min;

	cin.get();

}

char bepaalHoogsteEnLaagsteLetter(char *max, char *min, char a[], int lengte)
{
	*max = a[0];
	*min = a[0];


	for (int i = 1; i < lengte; i++)
	{
		if (*max < a[i])
			*max = a[i];
		//pointer oid?	
	}


	for (int i = 1; i < lengte; i++)
	{
		if (*min > a[i])
			*min = a[i];

	}

}


But now I get an error ''error C4716: 'bepaalHoogsteEnLaagsteLetter': must return a value.''
How do I send these two values to my main? I can NOT use a void!
you will need to return a pointer, a class, or a struct to return more than 1 item from a function, or a typedef can mask this as well. Or you can make 2 functions, one for max, one for min, and each can return 1 character.

you can do this for a simple quick solution to your problem. This is sort of a work-around to a weird requirement (must not make a void function that puts the answer into passed in arguments).


char * foo (....)
{
static char result[2]; //static forces the memory to persist so you can access it outside your function.
result[0] = whatever;
result[1] = something;
...
return result;
}


if you want to get more fancy,

struct mmtype
{
char maxval;
char minval;
};

mmtype maxminfunction(...)
{
...
mmtype result;
result.maxval = ...;
result.minval = ...;
..
return result;
}

for this you could hide your answers in a bigger type like integer and get it back out, but that is a bit obnoxious.
How do I send these two values to my main? I can NOT use a void!


Well, the existing code should work if you just added code to return something, anything from the function.

The assignement was originally in Dutch and said:

"Create a function determainHighestAndLowestChar that searches an array and returns the highest and lowest ASCII value. Print this value in your main function."

I don't see anything there to prohibit the use of void?

If you were asked to use two separate functions, then you could return the max from one and min from the other. But if you need to do it all in one function, your options are something like you already have, (or by reference, which would be the same design, but a change in syntax). Or, return two values as a single object, such as a struct, which is what jonnin has already suggested.
Last edited on
As jonnin has pointed out, since your assignment requires you to return the min and max values from one function that determines both of them from the array, you will need a class or a pointer to an array to achieve this result. You will use a pointer to an array, since using a class for this purpose would be significantly more complex. I'll illustrate the array example, and if you're curious I'll make an example for a class too.

The function will have to return an array which we will assign to another array to accomplish the instructions of the assignment.

Then, we will print out the values of that array.

Honestly though, the part where it says that the function has to return multiple items makes it more complicated and I believe is redundant. It would be completely acceptable or maybe better to have separate functions which return single items. Perhaps it is simply to make the student think how it's possible to do it with just one function returning multiple items.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
using namespace std;

char results[2];

char* determineHighestAndLowest(char a[], int length) {

	results[0] = a[0];//treat this as min
	results[1] = a[0];//treat this as max

	for (int i = 0; i<length; i++) {
		if (a[i] > results[1])
			results[1] = a[i];
	}

	for (int i = 0; i<length; i++) {
		if (a[i] < results[0]) {
			results[0] = a[i];
		}
	}

	return results;
}

void main() {

	const int length = 7;
	char a[length] = { 'a', 'b', 't', 'a', 'z', 'Z', 'X' };

	char* forPrint;
	forPrint = determineHighestAndLowest(a, length);
	cout << "Highest is: " << forPrint[1] << " and lowest is " << forPrint[0] << endl;

	system("pause>0");
}

I don't see anything there to prohibit the use of void?


The assignment specifically says to make a function that returns the highest and lowest ASCII value. For a function to return something, it cannot be a void.
Thank you all for your help. You guys were right, it did not explicitly say I couldn't use a void. I just thought it was mandatory to get all the points for the question.

I have read all your comments carefully and I have learned a lot from this thread, I guess that is what matters. I appreciate the amount of help I got on this website so quickly.

I managed to make it work with voids:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 #include <iostream>
#include <iomanip>

using namespace std;

void bepaalHoogsteEnLaagsteLetter(char *max, char *min, char a[], int lengte);

int main()
{
	const int lengte = 7;
	char min = 'a';
	char max = 'a';

	char a[lengte] = { 'c', 'b', 't', 'a', 'z', 'l', 'g' };
	
	bepaalHoogsteEnLaagsteLetter(&max, &min, &a[0], lengte); 
	
	cout << "Het minimum is: " << min << endl;
	cout << "Het maximum is: " << max;
	cin.get();

	//printf("%c, %c", min, max);

	cin.get();

}

void bepaalHoogsteEnLaagsteLetter(char *max, char *min, char a[], int lengte)
{
	for (int i = 0; i < lengte; i++)
	{
		if (*max < a[i])
			*max = a[i];

		if (*min > a[i])
			*min = a[i];
			
	}
}



cannot return from a void...
this could be a technicality.

void foo(inputs, *outputs)
is a standard pattern, where the user provides a pointer for outputs to be written into by the function.

type foo (inputs)
is also a pattern.

I would argue that both return a value. Your professor may not agree.

I disagree. When making a function, we first specify what kind of value it returns. It's in all cpp manuals and scripts. If it's a void function, it doesn't return a value.

Modifying a value through a pointer inside the function and returning a value are not the same thing. You make it seem like there is no semantic difference which is bad as then it becomes ambiguous what function returning a value actually means.
That is why I said it was possibly a technicality. If the requirement is full on technical text and properly written, I agree 100%. If the requirement is ramblings from a professor in a class, it could honestly go either way in terms of producing the assignment. If the class has yet to cover pointers, structs, or the other ways to return multiple values from the function, I would go with rambling professor. If these have been covered, do it technically. /shrug.


Topic archived. No new replies allowed.