Take a look at this array:
const int *c000[64][1][3] =
{
//Row 1
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 2
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 3
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 4
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 5
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 6*
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 7
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 8
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
};
Ignore the strange size and structure of the array, that's not what is important. I need to be able to use an array inside this array. For example, I have an array called h002:
const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0}; //01
I need to be able to use h002 from inside c000. Such as:
{ {h002, 0, 0} },
This compiles just fine, however
myVar = c000[0][0][0];
retrieves the address of h002. I need the first item in h002, not the address. I'm confused as to why it would even give me the adress of h002 at all? I would imagine *h002 would retrieve the address, but then that doesn't compile at all.
I have seen several questions on SO that closely resemble mine, such as this one:
Creating an array of int arrays in C?
I have tried that particular example above. It works when I have it in my main.c file, but when I try it in the same .c file that c000 and h002 are contained in, it fails to compile. Perhaps this has something to do with it? I'm not sure why it would, considering using h002 inside c000 returns the address of h002 just fine. It's strange that the code presented in the link above wouldn't compile outside of my main file.
I feel like I'm making some kind of obvious, little mistake. I've been messing around with this off and on for about 5 days now. Trial and error and research has gotten me nowhere. Researching was difficult enough, as there doesn't seem to be much on using arrays like this, and none of my findings significantly helped me.
Feel free to ask questions. I'll be glad to specify more information if needed.
EDIT: Thanks so much to Stephan Lechner for helping me solve my issue. To get the result I needed, I had to do
myVar = *(c000[0][0][0]);
This works perfectly. I can also add whatever number I like at the end to retrieve different indexes in h002. For example:
myVar = *(c000[0][0][0] + 7);
Hope this helps someone out in the future.
I think the basic misunderstanding is the meaning of const int *c000[64][1][3], which denotes a three dimensional array of pointers to int, but not a pointer to an 3D-array of integers. To demonstrate this, consider the following simplified examples together with compiler warnings:
int aSingleIntValue = 10; // integer value
int *aSinglePtrToIntValue = &aSingleIntValue; // pointer to an integer value
// 1D-array of integer values
int oneDArrayOfInt[5] = { 3,4,5,6,7 };
// 1D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *oneDArrayOfIntPtrOK[5] = { aSinglePtrToIntValue,0,0,0,0 };
// 1D-array of pointers to int; Note: 3,4,.. are int values, not pointers to int; Hence compiler complains:
// Warning: Incompatible integer to pointer conversion initializing "int *" with an expression of type "int"
int *oneDArrayOfIntPtrWarning[5] = { 3,4,5,6,7 };
// 3D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *threeDArrayOfIntPtrOK[5][5][5] = { { { aSinglePtrToIntValue,0,0 }, { 0,0,0} } };
// 3D-array of pointers to int; Warining: Incompatible integer to pointer conversion initializing "int *" with an expression of type "int"
int *threeDArrayOfIntPtrWarning[5][5][5] = { { { 3,4,5 }, { 2,3,1} } };
Just for showing a different meaning: if one would like to declare a pointer to an array of 5 integers, this could be expressed as follows:
typedef int arrayOf5Int_t[5];
arrayOf5Int_t *arrayOf5IntPtr = &oneDArrayOfInt;
Given that, let's explain the meaning of
const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0};
const int *c000[64][1][3] = { { { h002, 0, 0 } } };
Note that an element of c000 is a pointer to an integer, and note that variable h002 used in the context of the array initialiser decays to a pointer to an integer (pointing to the first element of h002). This is pretty much the same as declaring const int* ptrToH002 = h002, and the following print out demonstrates that this is actually the same:
const int *elemAt0x0x0 = c000[0][0][0];
const int *ptrToH002 = h002;
int isTheSame = elemAt0x0x0 == ptrToH002;
printf("pointer elemAt0x0x0 == ptrToH002 is %s", (isTheSame ? "true" : "false"));
// Prints: pointer elemAt0x0x0 == ptrToH002 is true
Hence, it should be clear that myVar = c000[0][0][0] retrieves an address, and not an integer value or an integer array. The address points to the first element of array h002.
Example of multidimensional array:
int main(){
int a1[] = {1,2,3,4};
int a2[] = {5,6,7,8};
int a3[] = {9,10,11,12};
int * superArr[3] = {a1,a2,a3};
printf("%d\n", superArr[2][1]);
}
You should be able to change your code to what you need using this example.
Related
I am working on a sudoku exercise using the backtracking algorithm using C. It prints the gameboard with the first solution it finds, however it does not stop there and continues the recursion by removing the fields of the gameboard and creates a new solution. The problem is somewhere in the solve function. Here is my approach:
#include "sudoku.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int field[SIZE][SIZE];
int initial[SIZE][SIZE];
/* Initializes the sudoku array.
* The field initial keeps the original start value for
* figuring out if a value is fixed or can be changed. */
void init(int begin[SIZE][SIZE]) {
memcpy(field, begin, SIZE * SIZE * sizeof(int));
memcpy(initial, begin, SIZE * SIZE * sizeof(int));
}
/* Retrieves the solution. NEEDED FOR AUTO-TESTING PURPOSES. */
void getResult(int result[SIZE][SIZE]){
memcpy(result, field, SIZE * SIZE * sizeof(int));
}
/* pretty prints the sudoku array */
void print() {
int row, col;
// print the first line
printf("||");
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
// loop through all rows of the array
for (row = 0; row < SIZE; row++) {
// print the line with field values
for (col = 0; col < SIZE; col++) {
if (col % SQRT_SIZE == 0)
printf("|| ");
else
printf("| ");
if (field[row][col] == 0)
printf(" ");
else
printf("%d ", field[row][col]);
}
// print the separation line;
// depending on the result of the modulo operation
// print a single or double line
printf("||\n||");
if (row % SQRT_SIZE == SQRT_SIZE - 1) {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
}
else {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("---++");
else
printf("---+");
}
printf("---||\n");
}
}
}
/* Checks if the value is valid and can be set into the field.
* The function returns false if the value is already present or
* has been one of the initial values. */
int checkValueInField(int value, int row, int col) {
int i, r, c;
int squareRow;
int squareCol;
// checks for initial values
if (initial[row][col] != 0) {
if (initial[row][col] == value)
return 1;
else
return 0;
}
// check horizontally
for (i = 0; i < SIZE; i++) {
if (field[row][i] == value) return 0;
}
// check vertically
for (i = 0; i < SIZE; i++) {
if (field[i][col] == value) return 0;
}
// check square
squareRow = row / SQRT_SIZE;
squareCol = col / SQRT_SIZE;
for (r = squareRow * SQRT_SIZE; r < squareRow * SQRT_SIZE + SQRT_SIZE; r++) {
for (c = squareCol * SQRT_SIZE; c < squareCol * SQRT_SIZE + SQRT_SIZE; c++) {
if (field[r][c] == value) return 0;
}
}
return 1;
}
/* Set a value in the sudoku field if the field is empty.
* The method returns false if the field contains a fixed number. */
int setValueInField(int value, int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = value;
return 1;
}
else if (initial[row][col] == value)
return 1;
return 0;
}
/* Removes a value in the sudoku field if it doesn't contain an initial value.
* The method returns false if the field contains a fixed number and cannot be
* removed. */
int removeValueFromField(int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = 0;
return 1;
}
return 0;
}
/* Returns the value in the field */
int getValueFromField(int row, int col) {
return field[row][col];
}
/* Return true after a valid solution for the sudoku has been found. */
int solve(int row, int col) {
print();
bool isSet = false;
if (row == 0 && col == 0) {
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) && getValueFromField(row, col) == 0) {
isSet = setValueInField(i, row, col);
if (isSet) {
solve(row, col);
}
if (row == SIZE - 1 && col == SIZE - 1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
}
if (row == SIZE - 1 && col == SIZE - 1) {
//Here is the solution, but then it continues after returning 1
for (int r = 1; r <= SIZE; r++) {
for (int c = 1; c <= SIZE; c++) {
if (getValueFromField(r, c) != 0) {
return 1;
}
}
}
}
if (row == SIZE - 1) {
row = 0;
col = col++;
}
else {
row = row++;
}
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) == 1) {
isSet = setValueInField(i, row, col);
solve(row, col);
if (row == SIZE - 1 && col == SIZE == -1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
return 1;
}
This is my header file:
#ifndef _SUDOKU_H_
#define _SUDOKU_H_
#define SIZE 9
#define SQRT_SIZE 3
void init(int begin[SIZE][SIZE]);
void getResult(int result[SIZE][SIZE]);
void print();
int checkValueInField(int value, int row, int col);
int setValueInField(int value, int row, int col);
int removeValueFromField(int row, int col);
int getValueFromField(int row, int col);
int solve(int row, int col);
This is the initial gameboard and its solution:
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
This is my testcase:
TEST_CASE("Test2", "Sudoku")
{
int result = 0;
int actual[SIZE][SIZE];
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
init(initial);
result = solve(0,0);
getResult(actual);
INFO("Test Case: valid Sudoku board failed.");
REQUIRE(memcmp(actual, expected, sizeof(initial)) == 0);
INFO("Test Case: return value not correct.");
REQUIRE(result == 1);
}
I'm trying to replicate a solution from javascript to Ruby where the idea is to build a grid from two arrays and then, running a search on both arrays, change certain elements in the grid.
I think my ruby solution is fairly similar but the grid doesn't look similar.
Any help is much appreciated
Arrays:
nums1 = [1,2,3,2,1]
nums2 = [3,2,1,4,7]
Javascript grid:
``
const dp = new Array(nums1.length + 1).fill(0).map(() => new Array(nums2.length + 1).fill(0));
console.log(dp)
output:
[
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ]
]
Ruby grid attempts:
1º attempt
dp = Array.new(nums1.length+1) {Array.new(nums2.length+1, 0)}
p dp
2º attempt:
dp = (0..n).map{|el| el = (0..m).to_a.map{|el| el = 0 }}
p dp
output is the same for both:
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
Thank you
I am working on cricket scoring Single page application in react.
It is using Redux to maintain its data and with every action i will be getting a new state.
My app has single rootReducer because everything is mingled. If a ball is thrown, batting and bowling both sides are updated.
The state is pretty complicated but I'm of opinion that it should be like this.
Please tell me if this state design is fine or I should somehow simplify it or change it?
var playerType = {
id: 0,
name: '',
// Batting stats
runs: 0,
four: 0,
six: 0,
ballsFaced: 0,
battingNumber: false,
isBatting: false,
isOnStrike: false,
isOut: false,
outType: '',
// Batting Walkin stats
walkInOver: 0,
walkInBalls: 0,
walkInTeamRuns: 0,
// Batting Out stats
walkoutWicket: 0,
walkoutOver: 0,
walkoutBalls: 0,
walkoutTeamRuns:0,
wicketBowler: 0,
wicketFilder: 0,
notOutPlayerId: 0,
notOutPlayerRuns:0,
// Bowling stats
overs: 0,
balls: 0,
overRuns: 0,
wickets: 0,
isBowling: false,
};
var teamType = {
id: 0,
name: "",
runs: 0,
overs: 0,
balls: 0, // This are only legal balls from 0 to 5
isTossWon: false,
players:playerType = []
};
// Initial State
var initialState = {
matchId: 0,
thisOver: [],
prevOver: [],
oversTotal: 0,
teamBatting: teamType,
teamBowling: teamType
}
Your thoughts?
I would have a match reducer that models everything in the match, such as:
A collection of batsmen
A collection of bowlers
Fields for each extra type (byes, legbyes, noballs, wides)
To that I would add "live" information such as:
The current batsman on strike
The current batsman off strike
The current bowler bowling
Note that I would leave out data that can be "derived" from other pieces of state. For instance, the total score can be derived from the sum of the batsmen's scores plus the sum of the extras.
A possible instance of the match state might look like:
{
batsmen: {
48: {
id: 48,
name: 'David Warner'
runs: 10,
balls: 18,
},
64: {
id: 64,
name: 'Matthew Renshaw',
runs: 2,
balls: 20,
},
},
byes: 2,
legbyes: 0,
noballs: 3,
wides: 0,
bowlers: {
82: {
name: 'Jimmy Anderson',
balls: 18,
runs: 6,
wickets: 0,
},
93: {
name: 'Stuart Broad',
balls: 17,
runs: 9,
wickets: 0,
},
},
batsmanOnStrike: 48,
batsmanOffStrike: 64,
currentBowler: 93,
}
You might want to dispatch an action for a discrete scoring event. e.g.
{
type: 'RUNS_SCORED',
runs: 3,
}
Your reducer might handle it in the following manner:
case 'RUNS_SCORED': {
const batsman = state.batsmen[state.batsmanOnStrike];
const bowler = state.batsmen[state.currentBowler];
return {
...state,
batsmen: {
...state.batsmen,
[state.batsmanOnStrike]: {
...batsman,
runs: batsman.runs + action.runs,
balls: batsman.balls + 1,
},
},
bowlers: {
...state.bowlers,
[state.currentBowler]: {
...bowler,
balls: bowler.balls + 1,
runs: bowler.runs + action.runs,
},
},
batsmanOnStrike: action.runs % 2 === 0 ? state.batsmanOnStrike : state.batsmanOffStrike,
batsmanOffStrike: action.runs % 2 === 0 ? state.batsmanOffStrike : state.batsmanOnStrike,
};
}
This example is imperfect and incomplete, but I hope it gives you the general idea.
I have code like this:
const char menu23[] = "2.3. ";
const char menu24[] = "2.4. ";
const char menu25[] = "2.5. ";
const char menu26[] = "2.6. ";
const char menu27[] = "2.7. ";
const char menu28[] = "2.8. ";
MenuEntry menu[] = // MenuEntry is a struct
{
{menu23, MENU2_OPTIONS, 22, 24, 23, 0, 0, 0}, // 23
{menu24, MENU2_OPTIONS, 23, 25, 2, 0, 0, 0}, // 24
{menu25, MENU2_OPTIONS, 24, 26, 0, 0, 0, 0}, // 25
{menu26, MENU2_OPTIONS, 25, 27, 0, 0, 0, 0}, // 26
{menu27, MENU2_OPTIONS, 26, 28, 0, 0, 0, 0}, // 27
{menu28, MENU2_OPTIONS, 27, 29, 0, 0, 0, 0} // 28
}
Can I replace it with this?
MenuEntry menu[] = // MenuEntry is a struct
{
{"2.3. ", MENU2_OPTIONS, 22, 24, 23, 0, 0, 0}, // 23
{"2.4. ", MENU2_OPTIONS, 23, 25, 2, 0, 0, 0}, // 24
{"2.5. ", MENU2_OPTIONS, 24, 26, 0, 0, 0, 0}, // 25
{"2.6. ", MENU2_OPTIONS, 25, 27, 0, 0, 0, 0}, // 26
{"2.7. ", MENU2_OPTIONS, 26, 28, 0, 0, 0, 0}, // 27
{"2.8. ", MENU2_OPTIONS, 27, 29, 0, 0, 0, 0} // 28
}
Is there any functional difference?
There is a big difference.
In this problem, first member of MenuItem must be char * type. (Otherwise first version of code in this question will fail with compile errors.)
char menu23[] = "2.3. "; This is a char array. String is stored in array's memory. Its lifetime is the same as array. If it's defined in a function, it will be destroyed after function returns. If it's defined as global variable, then there is no functional difference with second version. (But still different in implement perspective.)
{"2.3. ", MENU2_OPTIONS, 22, 24, 23, 0, 0, 0}, String in this line is a literal constant. It will be stored in memory's static area. Its lifetime will be the same as your application.
No differences. The first, though, can be more flexible in case you want to change the name of each menu later on (and in case the constant names are used in multiple locations).
I've written a small test case program in FORTRAN 90 which initializes a 3d array in slices. Can this same behavior be easily replicated in C?
program fortranEngine
real(4) , dimension(10,10) :: tmp
real(4) , dimension(10,10,3) :: p
tmp = RESHAPE( [ 0.973, 1.053, 0, 0, 0, 0, 0, 0, 0, 0, &
1.053, 1.080, 0, 0, 0, 0, 0, 0, 0, 0, &
1.010, 0.408, 0.442, 0, 0, 0, 0, 0, 0, 0, &
1.119, 0.900, 0.399, 0.762, 0, 0, 0, 0, 0, 0, &
1.211, 0.975, 0.845, 0.952, 1.105, 0, 0, 0, 0, 0, &
1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0, 0, 0, 0, &
1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0, 0, 0, &
1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0, 0, &
1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0, &
1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228] &
, [10,10] )
p(:,:,1) = tmp
...
end program fortranEngine
You can more or less do it in C99 or C2011, but it isn't as convenient as in Fortran. Beware initialization order; Fortran does it in one order (column-major) and C does it in the other (row-major). Ignoring that, you can do:
float tmp[10][10] =
{
{ 0.973, 1.053, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1.053, 1.080, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1.010, 0.408, 0.442, 0, 0, 0, 0, 0, 0, 0, },
{ 1.119, 0.900, 0.399, 0.762, 0, 0, 0, 0, 0, 0, },
{ 1.211, 0.975, 0.845, 0.952, 1.105, 0, 0, 0, 0, 0, },
{ 1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0, 0, 0, 0, },
{ 1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0, 0, 0, },
{ 1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0, 0, },
{ 1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0, },
{ 1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228 },
};
float p[3][10][10];
for (int i = 0; i < 3; i++)
memmove(p[i], tmp, sizeof(tmp));
Note that I moved the dimension [3] from the end of the declaration to the start of the declaration, though. The other way around would not make much sense in C. So, the notation is more or less available, but details of storage management make it less than obvious how to achieve exactly what you want.
Is this easy enough?
for(int i = 0 ; i < 10 ; ++i)
for(int j = 0 ; j < 10 ; ++j )
p[0][i][j] = tmp[i][j] ;