I'm trying to write a function that will take the first n integers and a variable number of functions and build a table that has the number as "i" in the first column and "function(i)" in the others.
But I cannot seem to be able to pass the addresses of my functions to the table generator because I get an access violation error. What did I do wrong?
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
typedef float(*f)(float);
// Some examples of f-type functions.
float square(float x) { return x*x; };
float root(float x) { return sqrt(x); };
float timesPi(float x) { return x * 3.14; };
// Display a table with first colon being the numbers from 1 to n,
// then the other columns to be f(i)
void table(unsigned int n, unsigned int nr_functions, ...)
{
va_list func;
va_start(func, nr_functions);
for (float i = 1; i <= n; i += 1)
{
printf("\n%6.0f |", i);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
// Main function
int main()
{
table(5, 3, &square, &root, ×Pi);
system("pause");
return 0;
}
For the example above
table(5, 3, &square, &root, ×Pi);
I want to get back
1 | 1.000 | 3.140 |
2 | 1.141 | 6.280 |
3 | 1.732 | 9.420 |
4 | 2.000 | 12.560 |
5 | 2.236 | 15.700 |
You need to reuse the variable section of the argument list, which means you need the va_start() and va_end() in the right places — inside the outer loop:
void table(unsigned int n, unsigned int nr_functions, ...)
{
for (unsigned int i = 1; i <= n; i++)
{
va_list func;
printf("\n%6.0f |", (double)i);
va_start(func, nr_functions);
for (unsigned int j = 0; j < nr_functions; j++)
{
f foo = va_arg(func, f);
printf("%6.3f |", foo(i));
}
va_end(func);
}
}
Otherwise, you're marching off the end of the list, except that you called va_end() inside the loop, leading to goodness only knows what damage.
Note that the loop should use integer arithmetic — with a consequential change to the printf() — here I cast the value, but changing the format to %6d would also be sane (possibly better, in fact).
With this function, I got the output:
1 | 1.000 | 1.000 | 3.140 |
2 | 4.000 | 1.414 | 6.280 |
3 | 9.000 | 1.732 | 9.420 |
4 |16.000 | 2.000 |12.560 |
5 |25.000 | 2.236 |15.700 |
Related
I would like to know what the [i] is for, and why my table is not displayed if I do not put it in.
Thank you!
#include <stdio.h>
void affiche(int* tableau, int taille);
int main()
{
int tableau[5] = { 12,15,50,20 };
affiche(tableau, 4);
return 0;
}
void affiche(int *tableau,int taille)
{
int i;
for (i = 0; i < taille; i++)`
{
printf("%d\n", tableau[i]);
}
}
[i] is the C language syntax for array notation.
tableau is an array of 5 integers.
int tableau[5] = {12,15,50,20}
In memory tableau has 5 slots allocated to it due to the above declaration.
Slots 0 through 3 are your initialization values.
Slot 4 is uninitialized (though modern c compilers might set this value to null or zero (0).
tableau
+-----------------------+
index | 0 | 1 | 2 | 3 | 4 |
+-----------------------+
value | 12 | 15 | 50 | 20 | ? |
+-----------------------+
inside function affiche(...) this statement
printf("%d\n", tableau)
tries to print to console a single integer (%d) followed by a newline (\n)
But tableau is an array of 5 integers.
So you need the array index to select a specific integer individually like this:
printf("%d\n", tableau[0]) // output: 12
printf("%d\n", tableau[1]) // output: 15
printf("%d\n", tableau[2]) // output: 50
printf("%d\n", tableau[3]) // output: 20
printf("%d\n", tableau[4]) // output: unknown, possible exception
or by function call to affiche(tableau, 4); which ends at index 3
void affiche( int *tableau, int taille)
{
int i;
for( i = 0; i < taille; i++){
printf( "%d\n", tableau[i] );
}
}
Which outputs:
12
15
50
20
The code ran differently than I predicted, I think *(score+i*n+j) is problematic, it could also be a problem elsewhere, I'm not quite sure, but I don't know how to modify it.
#include <stdio.h>
#define STUD 30 // Maximum number of students possible
#define COURSE 5 // The maximum number of possible exam subjects
void Total(int *score, int sum[], float aver[], int m, int n);
void Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{
int i, j, m, n, score[STUD][COURSE], sum[STUD];
float aver[STUD];
printf("Enter the total number of students and courses:\n");
scanf("%d %d",&m,&n);
printf("Enter score:\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &score[i][j]);
}
}
Total(*score, sum, aver, m, n);
Print(*score, sum, aver, m, n);
return 0;
}
void Total(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
sum[i] = 0;
for (j = 0; j < n; j++)
{
sum[i] = sum[i] + *(score + i * n + j);
}
aver[i] = (float) sum[i] / n;
}
}
void Print(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
printf("Result:\n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%4d\t", *(score + i * n + j));
}
printf("%5d\t%6.1f\n", sum[i], aver[i]);
}
}
Example of a program running:
Enter the total number of students and courses:
2 3↙
Enter score:
90↙
95↙
97↙
82↙
73↙
69↙
Result:
90 95 97 282 94.0
82 73 69 224 74.7
Compiling your program yields no warnings or errors. Running it with the sample input you've provided yields:
Enter the total number of students and courses:
2 3
Enter score:
90
95
97
82
73
69
Result:
90 95 97 282 94.0
404780 0 82 404862 134954.0
This is correct for the first set of scores, but not the second. As you intuited, this means your math for accessing the array via pointer math is probably wrong.
Consider what your array actually looks like in memory. You've allocated on the stack an array that looks like:
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
Your example input has filled it like this:
+---+---+---+---+---+
| 90| 95| 97| | |
+---+---+---+---+---+
| 82| 73| 69| | |
+---+---+---+---+---+
...
If you want to access the first element of the second row, you need your offset to be i * 5 rather than i * 3 which is what happens when you use i * n. This 5 we can get from your constant COURSE.
*(score + i * COURSE + j)
When you use a different offset you get data which has not been initialized, which is why you see garbage values. If you initialize all of the values in your array to 0, but leave your code otherwise unchanged, you can see this in action.
int i, j, m, n, score[STUD][COURSE] = {0}, sum[STUD];
Enter the total number of students and courses:
2 3
Enter score:
90
95
97
82
73
69
Result:
90 95 97 282 94.0
0 0 82 82 27.3
As you note, the problem is your array accesses -- you use score[i][j] in main to fill the array and then *(score + i * n + j) in your Total and Print functions to try to access it, and these are different and incompatible. The easiest fix is probably just to fix the declarations of Total and Print to match the score you are using:
void Total(int score[][COURSE], int sum[], float aver[], int m, int n);
void Print(int score[][COURSE], int sum[], float aver[], int m, int n);
Then you can just use score[i][j] in them and everything should work. You would also pass score as just score instead of *score.
Alternately, change the declaration of score to score[STUD*COURSE] and use *(score + i * n + j) (or score[i*n + j]) in main to access it like you do in Total and Print.
OP is unclear why the code uses #defines to define values for rows and columns of the array score, then goes on to use scanf() to enter new values that may or may not conflict with the #defines, or even overflow the array memory. Either method works, but using both together confuse things. Pick one or the other.
Aside: If a dynamic sized array is necessary, then it can be created as a pointer, or pointers to allocated memory, or by use of a VLA
eg: A short example of using user input with dynamic memory allocation to create the array sized to the need of the moment:
Note: following method allows you to use plain array notation to assign values:
score[i][j] = someValue://easy to use and readable
//as opposed to
*(score + i*n + j) = someValue;// cumbersome to use and read
Example:
int student, course;//using descriptive variables
printf("Enter the total number of students and courses:\n");
scanf("%d %d",&student,&course);
int (*score)[course] = create_arr_2d (student, course);
if(score)
{ //use score
...
free(score);
}
Where create_arr_2d(...) is defined:
void * create_arr_2d (size_t x, size_t y)
{
int (*ptr_2)[x] = malloc( sizeof (int *[y]) ); //allocate a true 2D array
if(ptr_2)
{
memset(ptr_2, 0, sizeof **ptr_2);
}
return ptr_2;
}
(credit for method)
Addressing your code as is. First, the following creates variables, but does not initialize any of them:
int i, j, m, n, score[STUD][COURSE], sum[STUD];
float aver[STUD];
To eliminate some of the issues you may be seeing, initialize:
int i=0, j=0, m=0, n=0, score[STUD][COURSE]={{0}}, sum[STUD]={0};
float aver[STUD]={0};
In the function prototype in your given code:
Total(int *score, int sum[], float aver[], int m, int n)
int *score
suggests a pointer to a single dimensional array is being passed, but if it is being used to represent score[STUD][COURSE], then it should be passed as `score[m][n], with the prototype changed as:
Total(int m, int n, int score[m][n], int sum[m], float aver[m]);
Then called as:
Total(STUD, COURSE, score[STUD][COURSE], sum[STUD], aver[STUD]){...}
Note, this arrangement makes use of VLA type function arguemnts
Note also, an array such as: (shortened from your values for easier viewing)
int m = 5;
int n = 4
int array[m][n] = {{0}}
creates a single contiguous block of memory, conceivably looking like this in memory:
`|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|...`
0 5 10 15 20
Where all of the elements can be accessed in a for loop like this:
for(int i=0; i<m; i++
for(int j=0;j<n;j++)
*(array + i*n + j);
...
...
Is it possible to modify the contents of the memory address of the return value of a function? functions return the value of a locally defined variable.
In the following example, compiled for my machine (x86-64) without warnings:
#include <stdio.h>
int get_val1()
{
int ret = 1;
return ret;
}
int get_val2()
{
int ret = 2;
return ret;
}
int get_val3()
{
int ret = 3;
return ret;
}
void redefine_ints(int *val1, int *val2, int *val3) {
*val1 = 10;
*val2 = 11;
*val3 = 12;
}
void print_and_redefine_ints(int val1, int val2, int val3) {
printf("val1 %d val2 %d val3 %d\n", val1, val2, val3);
redefine_ints(&val1, &val2, &val3);
printf("rval1 %d rval2 %d rval3 %d\n", val1, val2, val3);
}
int main()
{
print_and_redefine_ints(get_val1(), get_val2(), get_val3());
return 0;
}
I get the next output:
val1 1 val2 2 val3 3
rval1 10 rval2 11 rval3 12
This is the expected output, but how is it possible? Where are these variables stored?
A draw may explain more than some text. I'll use only 1 get_val1() in that example.
print_and_redefine_ints(get_val1());
|
|
[CALL]
|
|
V
int get_val1()
{
int ret = 1;<----------------------------------------------------+
return ret; |
} | |
| |
[COPY OF VALUE] |
| |
| |
+---+ |
| |
| |
V |
void print_and_redefine_ints(int val1) { |
printf("val1 %d\n"); ^ |
redefine_ints(&val1); | |
| +--------------------------------------------+ |
| | |
[POINTER AKA REFERENCE] | |
| | |
| | |
V | |
void redefine_ints(int *val1) { | |
*val1 = 10; //<---- the value is changed, then its referenced value (this one, NOT THIS ONE) is changed too
} |
|
+---+
|
[VALUE CHANGED]
|
|
V
printf("rval1 %d\n", val1);
printf("original val1 %d\n", get_val1()); //if you add this line, you'll notice the returned value of get_val1() is still 1
}
Yes this is well-defined C.
The anonymous temporary ints created by get_val...() have a lifetime contemporaneous with the entire statement in which they are created.
But note that you take a value copy of each of these ints when you call print_and_redefine_ints so there's nothing particularly special going on here.
(Note that you would not be able to bind pointers to the anonymous temporary ints to int* function parameters though.)
Is it possible to modify the contents of the memory address of the return (value) of a function?
No, it is not.
However, that is not the case here. In your code, the return values of get_val<n>() function calls are stored in the function parameters int val1, int val2, int val3. They are local to the called function. The lifetime of those variables are the function execution period.
Quoting C11, chapter §6.2.1,
[...] If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block. [....]
and, from §6.9.1, Function definition,
Each parameter has automatic storage duration; its identifier is an lvalue
Thus, just like any other local variable, you can modify the content of those variables using their address.
Whenever I run my code I get a message: Segmentation fault: 11
My question is why this message is popping up. I have done some research prior to this and have tried to fix it but I still have the same message pop up. Please review my code!
To give some context to my code: The goal of this program is to implement the Connect Four game between a computer and a human player. Functions are to be implemented in the file connect4_functions.c. Forward declarations of these functions are in the file connect4_functions.h. connect4.c contains the main () functions.
The code (connect4_functions.c) is below:
#include "connect4_functions.h"
int print_welcome(void) // PROBLEM: returnerer alltid 1
{
printf ("*** Welcome to the Connect Four game!!! ***\n");
printf ("Would you like to make the first move [y/n]: ");
if (getchar() == 'N' || getchar() == 'n') return 2;
else return 1;
while (getchar()!= '\n');
}
void display_board(int board[][BOARD_SIZE_VERT])
{
int i, j;
for (i = BOARD_SIZE_VERT-1; i >= 0; i--)
{
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 0; j < BOARD_SIZE_HORIZ; j++)
{
switch (board[j][i])
{
case 0: printf ("| "); break;
case 1: printf ("| O "); break;
case 2: printf ("| X "); break;
}
}
printf ("|\n");
} // end for
for (j = 0; j < BOARD_SIZE_HORIZ; j++) printf ("+---");
printf ("+\n");
for (j = 1; j <= BOARD_SIZE_HORIZ; j++) printf (" %d ", j);
printf ("\n");
} //end function display_board
int random_move(int board[][BOARD_SIZE_VERT], int computer_num)
{
int m = (rand() % BOARD_SIZE_HORIZ) + 1;
if (!is_column_full(board,m))
{
update_board(board,m,computer_num);
return m;
}
else return random_move(board,computer_num);
}
int player_move(int board[][BOARD_SIZE_VERT], int player_num)
{
int m;
printf ("Please enter your move: ");
scanf ("%d", &m);
while (getchar() != '\n');
if ( 0 > m || m > BOARD_SIZE_HORIZ)
{
printf ("Not a valid move. Enter a column number!\n");
return player_move(board, player_num);
}
if (is_column_full(board, m))
{
printf ("This column is full. Try again!\n");
return player_move(board, player_num);
}
update_board(board,m,player_num);
return m;
}
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move)
{
int m, count = 0;
if (check_winner(board, last_move))
{
printf("Player %c won!\n", ( check_winner(board,last_move) == 1 ? '1' : '2' ) );
return true;
}
for (m = 0; m < BOARD_SIZE_HORIZ; m++) if ( is_column_full(board, m) ) count++;
if (count == BOARD_SIZE_HORIZ)
{
printf ("Tie game!\n");
return true;
}
else return false;
}
bool is_column_full(int board[][BOARD_SIZE_VERT], int m)
{
return (board[m-1][BOARD_SIZE_VERT-1]);
}
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num)
{
int i;
for ( i = 0; i < BOARD_SIZE_VERT ; i++)
{
if (!board[m-1][i])
{
board[m-1][i] = player_num;
return;
}
}
}
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
printf ("row = %d\n", row);
// Vertical
for (i = 0; i < BOARD_SIZE_VERT; i++)
{
if (board[last_move-1][i] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
// Horizontal
for (i = 0; i < BOARD_SIZE_HORIZ; i++)
{
if (board[i][row] == board[last_move-1][row]) count++;
else count = 0;
if (count == 4) return board[last_move-1][row];
else return 0;
}
count = 0; // reset
return 0;
}
The code for connect4_functions.h (cannot be changed) is below:
#ifndef CONNECT4_FUNCTIONS
#define CONNECT4_FUNCTIONS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define BOARD_SIZE_HORIZ 7
#define BOARD_SIZE_VERT 6
int print_welcome(void);
void display_board(int board[][BOARD_SIZE_VERT]);
int random_move(int board[][BOARD_SIZE_VERT], int computer_num);
int player_move(int board[][BOARD_SIZE_VERT], int player_num);
bool check_win_or_tie(int board[][BOARD_SIZE_VERT], int last_move);
bool is_column_full(int board[][BOARD_SIZE_VERT], int m);
void update_board(int board[][BOARD_SIZE_VERT], int m, int player_num);
int check_winner(int board[][BOARD_SIZE_VERT], int last_move);
int best_move(int board[][BOARD_SIZE_VERT], int computer_num);
#endif
The code for connect4.c (also cannot be changed) is below:
#include "connect4_functions.h"
int main()
{
int board[BOARD_SIZE_HORIZ][BOARD_SIZE_VERT] = { {0} };
int player_num, computer_num;
int last_move;
/* Ask Alice if she wants to go first */
player_num = print_welcome();
if (player_num == 1) computer_num = 2;
else computer_num = 1;
/* If Alice wants to go first, let her make a move */
if (player_num == 1)
{
display_board(board);
last_move = player_move(board,player_num);
display_board(board);
}
/* The main loop */
while (1)
{
/* Make a computer move, then display the board */
last_move = random_move(board,computer_num);
printf("Computer moved in column: %d\n", last_move);
display_board(board);
/* Check whether the computer has won */
if (check_win_or_tie(board,last_move)) return 0;
/* Let Alice make a move, then display the board */
last_move = player_move(board,player_num);
display_board(board);
/* Check whether Alice has won */
if (check_win_or_tie(board,last_move)) return 0;
} /* end of while (1) */
} /* end of main() */
Also, if you would like to see the original pdf it is linked below:
Link to pdf
The output is:
*** Welcome to the Connect Four game!!! ***
Would you like to make the first move [y/n]: y
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Please enter your move: 4
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
Computer moved in column: 1
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| | | | | | | |
+---+---+---+---+---+---+---+
| X | | | O | | | |
+---+---+---+---+---+---+---+
1 2 3 4 5 6 7
row = -355898527
Segmentation fault: 11
(If you have any questions about the context or purpose please don't hesitate to ask!)
Not having actually run the code, I believe the issue may be that count is not initialized in check_winner:
int check_winner(int board[][BOARD_SIZE_VERT], int last_move)
{
int i, row, count;
// Find row
for (row = 0; row < BOARD_SIZE_VERT; row++)
{
if (board[last_move-1][row]) count++;
}
row = count;
// WHAT IF IT EXITS THE for () WITHOUT board[last_move-1][row] being non-zero?
// HINT: count can be anything!
printf ("row = %d\n", row);
You then use row as an access into an array, and boom! You've accessed memory outside your permissions.
In the check_winner function you don't initialise the variable count. I get an unitialised variable runtime error, yet if I continue ahead a couple of lines later you then set:
row = count;
Which in my case is setting row to -858993459;
A couple of lines down in that same function you write:
if (board[last_move - 1][i] == board[last_move - 1][row]) count++;
// You use "row", an initialised variable as the index
// for the second subscript operator of board.
And that's where I get:
Access violation reading location 0x0000005663E82BB4. occurred
I think there should have been a warning shown about this unitialised variable. And honestly, I don't know if that's all that's wrong with it, but it looks like a pretty good game.
First of all, to be able to solve your problem, you should make sure everything that might be printed before the crash, has been printed. In this goal, you should add a fflush(stdout); instruction after each of your printing instructions
secondly, if this doesn't make clear at what place you program crashes, you should add supplementary tracing instruction inside the piece of code where it happens.
And then, when you have identified which instruction causes de crash, you should print it's variables to check if their values are what you expect.
Alternatively, you can use the assert instruction to make sure the variable values are all in the expected ranges.
If I have a multidimension pointer representation of a grid like so
char **p;
int w; // width (i.e. number of columns)
int h; // height (i.e. number of rows)
How do I go about creating a copy that is rotated by 90 degrees clockwise for NxM grid?
I've tried mallocing the height as the new width, and width as new height then transposing the values. Then I was going to finish by reversing the values of the row but I haven't managed to do this.
Actual transposition is moderately painful: you have to move every element from "where it is now" to "where it should be in the transposition". If you really do have a pointer p pointing to the first of M pointers, and each of those M pointers points to the first of N chars (used as if it's an array of size M of arrays of size N of chars):
+---+ +---+---+---+---+
p ---> | * | ----> | a | b | c | d |
+---+ +---+---+---+---+
| * | --
+---+ \ +---+---+---+---+
| * | -----------> | i | j | k | l |
+---+ \ +---+---+---+---+
\
\ +---+---+---+---+
--> | e | f | g | h |
+---+---+---+---+
then you need a new pointer (which I will call q) pointing to the first of N pointers, each of which points to the first of M chars (note: this is a different transposition than you asked for):
+---+ +---+---+---+
q ---> | * | -----> | a | e | i |
+---+ +---+---+---+
| * | --
+---+ \
| * |etc \ +---+---+---+
+---+ ---> | b | f | j |
| * |etc +---+---+---+
+---+
However, if you can live with relatively annoying subscript-writing and any cache miss effects on your runtime, you can simply access p[i][j] as p[j][i] or p[N-1-j][i], etc., to "pretend" that things are transposed. This might be easiest with some macros:
#define ORIENTATION_A(p, M, N, i, j) ((p)[i][j])
#define ORIENTATION_B(p, M, N, i, j) ((p)[(N)-1-(j)][i])
/* etc */
(note: none of the above is tested).
When using type char **, since the fixed-size solution is already posted I thought I would chime in with a dynamic, \0 terminated solution that works with various-sized arrays. If it is possible to terminate the arrays h and w can be omitted. This function can figure out the h and w. Of course it may be changed to support h and w, but the powers that be would rather I get back to work funding their empire rather than providing free help.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
/* rotate_array
w h
**p _______ **q ___
|A B C D|\0 ===> |E A|\0
h |E F G H|\0 ==> |F B|\0 w
NULL----- |G C|\0
|H D|\0
NULL-
*/
char **rotate_array(char **p) {
int w,h,hh;
char **q;
for (w=0;p[0][w];w++);
for (hh=0;p[hh];hh++);
if (!(q = malloc(w * sizeof q))) {
perror ("malloc");
exit (1);
} fprintf (stderr,"made it\n");
for (w=0;p[0][w];w++) {
if (!(q[w] = malloc(hh))) {
perror ("malloc");
exit (1);
} for (h=0;h<hh;h++) {
q[w][hh-h-1] = p[h][w];
} q[w][h]='\0';
} q[w]=NULL;
return q;
} void free_array(char **p) {
int h;
for (h=0;p[h];h++) {
free (p[h]);
} free (p);
}
// main
int main (int argc, char **argv) {
int h;
char *p[3]={"ABCD","EFGH",NULL};
char **q;
for (h=0;p[h];h++) {
printf ("%s\n",p[h]);
} printf ("\n");
q = rotate_array (p);
for (h=0;q[h];h++) {
printf ("%s\n",q[h]);
} free_array (q);
return 0;
}