0

I was looking at some code from google and something caught my eye.

#include <iostream>

using namespace std;

const int kStudents = 25;
const int kProblemSets = 10;

// This function returns the highest grade in the Problem Set array.
int get_high_grade(int *a, int cols, int row, int col) {

  int i, j;
  int highgrade = *a;

  for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
      if (*(a + i * cols + j) > highgrade)  // How does this line work?
        highgrade = *(a + i*cols + j);

  return highgrade;
}

main() {

 int grades[kStudents][kProblemSets] = {

   {750, 700, 85, 720, 84},
   {85, 92, 93, 96, 86},
   {95, 90, 103, 76, 97},
   {65, 62, 73, 84, 73}

 };

 int std_num = 4;
 int ps_num = 5;
 int highest;

 cout << *(int *)grades << endl;

 highest = get_high_grade((int *)grades, kProblemSets, std_num, ps_num);
 cout << "The highest problem set score in the class is " << highest << endl;
}

It was (int *)grades. I've never seen that before in any tutorial before so it caught me off guard. I used cout << *(int *)grades << endl; to determine that it was a pointer but I've never seen a pointer with that syntax.

Can anyone explain how it works? Thanks.

2 Answers 2

2

grades is an array of array of int objects.

The pointer expression grades is implicitly converted in most contexts to a pointer to the array's initial (0th) element, so the expression grades by itself is of type int(*)[kProblemSets], a pointer to an array of int.

The (int*) cast converts this pointer value from one pointer type to another, and the * dereferences the resulting converted pointer, yielding an int result.

This is questionable; I don't think there's any guarantee that the code will do what you expect. If the intent is to print the value of the first element of the first row of the array, just use:

std::cout << grades[0][0] << std::endl;

(Incidentally, main() should beint main(). C++ has no "implicit int rule; you have to specify the return type explicitly.)

Sign up to request clarification or add additional context in comments.

4 Comments

If you change 750 to 70 then cout << *(int *)grades << endl; will output 720, a.k.a the highest value.
I wasn't looking at the code that computes the highest value, just the cout << *(int *)grades << endl; that you asked about. When I change 750 to 70, that statement prints 70.
Oh, my misunderstanding. Sorry. You're right. Thanks for clarifying.
*(int *)grades is guaranteed to work , there could be debate over whether the function performs an out-of-bounds array access (reading off the end of the first row)
2

As grades is a 2d array, when cast to a pointer, you get a pointer to the first item of the array. This is what the (int*) does. The * at the front gets the value of the pointer - which as said, is the first item, which in this case has the value 750.

It's the equivalent to grades[0][0].

3 Comments

When you get rid of all the code an simply have the 2d array and cout << *(int *)grades << endl; then it will give a compilation error. And if you change the position of the highest value in the program it will output that instead of the first.
@TCG: Are you sure about that? grades is an array expression, which is converted to a pointer. The (int*) cast converts it to a different pointer type which is questionable but legal. The * dereferences the resulting pointer, yielding a result of type int. I don't think the behavior is well defined, but it should compile. (A compiler could warn about it, but is not required to.)
I checked it without the function get_high_grade and the last two lines of code in the main function. It did not compile as it gave an error, that's why I was so confused.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.