Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So I'd like to represent a rectangular maze of say dimensions 5x4 (rows x columns) using a 2D array in C language. However I am having trouble specifying what actually needs to be put into the 2D array.
int a[5][4] = {
{},
{},
{},
{},
{},
};
Here is the skeleton of the 2D array, in each row there will be 4 values, I assume that each of these values is a single integer that tells us the properties of a cell in the maze. My problem is, is that really enough? How does a single value tell a robot weather there are 3 walls, 2 walls etc
Someone please enlighten me D:
use specific bits for specific properties of the room
#define ROOM_WALL_ABOVE (1 << 0)
#define ROOM_WALL_LEFT (1 << 1)
#define ROOM_WALL_BELOW (1 << 2)
#define ROOM_WALL_RIGHT (1 << 3)
#define ROOM_DOOR (1 << 4)
int a[5][4] = {0};
a[0][0] = ROOM_WALL_ABOVE | ROOM_WALL_LEFT;
if (a[x][y] & ROOM_WALL_RIGHT) printf("Cannot walk right.\n");
You could use a struct matrix
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
struct walls
{
bool N; // true = wall false = no wall
bool S; // true = wall false = no wall
bool W; // true = wall false = no wall
bool E; // true = wall false = no wall
};
int main()
{
struct walls maze[5][4];
// reset
memset(maze, 0x00, sizeof(maze));
// init
maze[0][0].N = false;
maze[0][0].S = true;
maze[0][0].W = true;
maze[0][0].E = false;
// YOUR STUFF
return 0;
}
Related
I am working with structs in a game I am making, and the struct holds information about the humanoid (position, speed, etc). I have a struct for the player and one for a zombie. I'm adding the zombie struct onto an array (and plan on doing the same for other enemies) in order to iterate over them every frame loop and advance them one step forward or work game logic out. (For the record, the game runs on the Nintendo DS). Unfortunately, I can't seem to modify values of the struct via an array index, as the values don't change. Modifying the struct directly works, but it would be a huge pain to update every struct independently (reason for looping through an array of the structs). Here is the code that goes in more depth:
typedef struct{
int x;
float y;
float speed;
bool isSwordActive;
bool facingRight;
} humanoid;
void game(){
humanoid player = {12, 12, 0, false, false};
humanoid zombie = {226, 12, 0, false, false};
humanoid objects[1] = {zombie};
while(1){
// This works
zombie.y += zombie.speed;
zombie.speed += 0.125;
// This does not work
for(int i = 0; i < sizeof(objects)/sizeof(objects[0]); i++){
objects[i].y += objects[i].speed;
objects[i].speed += 0.125;
}
}
}
Could someone please explain why this doesn't work, and a possible solution? Thank you!
objects should be a pointer array. You were copying the data into the array, so the original objects were untouched.
Here is the refactored code. It is annotated:
#define bool int
#define false 0
#define true 1
typedef struct {
int x;
float y;
float speed;
bool isSwordActive;
bool facingRight;
} humanoid;
void
game()
{
humanoid player = { 12, 12, 0, false, false };
humanoid zombie = { 226, 12, 0, false, false };
// ORIGINAL
#if 0
humanoid objects[1] = { zombie };
// FIXED
#else
humanoid *objects[2] = { &zombie, &player };
#endif
// ORIGINAL
#if 0
while (1) {
// This works
zombie.y += zombie.speed;
zombie.speed += 0.125;
// This does not work
for (int i = 0; i < sizeof(objects) / sizeof(objects[0]); i++) {
objects[i].y += objects[i].speed;
objects[i].speed += 0.125;
}
}
#endif
// BETTER
#if 0
while (1) {
// This works
zombie.y += zombie.speed;
zombie.speed += 0.125;
// This does not work
for (int i = 0; i < sizeof(objects) / sizeof(objects[0]); i++) {
objects[i]->y += objects[i]->speed;
objects[i]->speed += 0.125;
}
}
#endif
// BEST
#if 1
while (1) {
// This works
zombie.y += zombie.speed;
zombie.speed += 0.125;
// This does not work
for (int i = 0; i < sizeof(objects) / sizeof(objects[0]); i++) {
humanoid *obj = objects[i];
obj->y += obj->speed;
obj->speed += 0.125;
}
}
#endif
}
In the above code, I've used cpp conditionals to denote old vs. new code:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
This works, thank you! Pointers are always screwing me over. If you don't mind, could you explain why the best solution is better than the better solution? Is it performance-wise? Wouldn't performance slow down a bit if there are too many objects and making new variables for each object? Thank you! –
JuanR4140
We're not creating/copying the contents of the array element (e.g. 20 bytes). We're just calculating the address of the array element. This must be done anyway, so no extra code.
This is a fundamental difference and I think this is still a point of confusion for you.
If we compile without optimization, the "BETTER" solution would reevaluate objects[i] three times. Before it can "use" object[i], the value there must be fetched and placed into a CPU register. That is, it would do:
regA = &objects[0];
regA += i * sizeof(humanoid);
regA = *regA;
regA->something
Again, this is repeated 3 times:
regA = &objects[0];
regA += i * sizeof(humanoid);
regA = *regA;
regA->something
regA = &objects[0];
regA += i * sizeof(humanoid);
regA = *regA;
regA->something
regA = &objects[0];
regA += i * sizeof(humanoid);
regA = *regA;
regA->something
If we compile with optimization, the generated code would be similar to the "BEST" solution. That is, the compiler realizes that objects[i] is invariant within the given loop iteration, so it only needs to calculate it once:
regA = &objects[0];
regA += i * sizeof(humanoid);
regA = *regA;
regA->something
regA->something
regA->something
Note that the compiler must always put the calculated address value into a register before it can use it. The compiler will assume that obj should be in a register. So, no extra code generated.
In the "BEST" version, I "told" the compiler how to generate the efficient code. And, it would generate the efficient code without optimization.
And, doing obj->something in several different places is simpler to read [by "humanoid" programmers ;-)] than objects[i]->something in multiple places.
This would show its value even more with a 2D array.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
task condition: Using the structure type and preprocessor directives, compile a program for input information about N types of computer equipment, which is known: manufacturer, type (printer, scanner, laptop, mouse, keyboard), color, model), get the price by the formula y = 3x ^ 2 + 4x-2, where x is the number of the option plus N. Sort the prices for computer equipment by the method of "bubbles" in ascending order.
#define N 5
#define M 15
#define PRI(X) 3*X*X+4*X-2
typedef struct Ctechnology
{
char firma[M];
char type[M];
int price[N];
} comp;
int main()
{
comp a;
printf("Firm, type, price - (y=3x^2+4x-2)\n ");
for (int i = 0; i < N; i++)
{
a.price[N] = PRI(((i + 1)+N)); // there is a problem
printf("%d) ", i + 1);
scanf("%s %s", a.firma, a.type);
printf("\n | [%d] | Firm %10s | Type %10s | Price %10d |\n", i + 1, a.firma, a.type, a.price[N]);
}
return 0;
}
Running
#define N 5
#define M 15
#define PRI(X) 3*X*X+4*X-2
price[N] = PRI(((i + 1)+N));
through gcc -E (which runs the preprocessor), we get
price[5] = 3*((i + 1)+5)*((i + 1)+5)+4*((i + 1)+5)-2;
In general, you may want to add parentheses around the Xes in your directive, so they're correctly grouped no matter the input:
#define PRI(X) 3*(X)*(X)+4*(X)-2
->
price[5] = 3*(((i + 1)+5))*(((i + 1)+5))+4*(((i + 1)+5))-2;
Then, of course, there's the matter of price[N] always being an out-of-bounds access.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
The community is reviewing whether to reopen this question as of 10 months ago.
Improve this question
When I send 255 data, all data were sent normally.
However, if I send more than 255 bytes of data, it gets corrupted.
It feels like I have only one page, which can hold only 255 bytes of data. So if I send more than 255 bytes of data, data gets mixed up and corrupted.
its fixed now!but 257~end of array of data seems not saving..
123_DATA_SIZE = 32;
123_PACKAGE_SIZE = (123_DATA_SIZE+2)
123_tbl_1_SIZE = sizeof(123_tbl_1)
123_tbl_1 = array of data i.e.{0x20,0x24,..,0x67) //assume there are
1024bytes of data
123_SLAVE_ADDR = 0x24 /////(initial slave address)
unsigned char ProgramCommand(WORD wAddr)
{
BYTE I2c_ProgramCommand[123_PACKAGE_SIZE]; // command + addr + data size
unsigned char Release_ProgramCommand[3] = {00,00,00};
unsigned char Low_ByteCommand[3] = {0x0E,0xFF,0xFF};
unsigned int count, count1;
Adding =0;
Adding1 = 0;
wAddr =0;
{
unsigned char I2c_OnlyOnceProgramCommand[3] = {0xE0,0x00,0x13};
if (i2c_123_iSP_Write(123_SLAVE_ADDR, I2c_OnlyOnceProgramCommand, 3)==0)
return 0;
}
for(count = 0; count < (123_tbl_1_SIZE/123_DATA_SIZE); count++)// size
of data divide by 32
{
I2c_ProgramCommand[0] = 0x90;
I2c_ProgramCommand[1] = wAddr;
changed below
if(count%(7+Adding) ==0)
{
SetAddressHighbyteCommand(0);
Adding +=8; // for additional pages..
// Adding1 +=1;
}
now i changed above part to
if(count%8 ==0) //
{
SetAddressHighbyteCommand((BYTE)(wAddr >> 8));
}
and this worked! sending more than 256 bytes still shown me correct data.
for( count1 = 0; count1<123_DATA_SIZE; count1++) // count1 runs total 32 times.
{
I2c_ProgramCommand[2+count1] = 123_tbl_1[wAddr+count1];
}
if( i2c_123_iSP_Write(123_SLAVE_ADDR, I2c_ProgramCommand,
123_PACKAGE_SIZE) == 0)
return 0;
SetAddressHighbyteCommand(0);
if(123_iSP_Write(123SLAVE_ADDR, Release_ProgramCommand, 3)==0)
return 0;
wAddr += 32;
}
return 1;
}
now the problem is, 257~512 bytes of data seems not saving properly.
read command is:
void ReadCommand(WORD wAddr)
{
unsigned char u8ReadBuffer[256];
unsigned int u16Cmd_LowAddr = 0xD000;
if(wAddr & 0xFF00)
{
SetAddressHighbyteCommand((BYTE)(wAddr >> 8));
}
u16Cmd_LowAddr |= (wAddr & 0x00FF);
i2c_123_iSP_Read(0x25,u16Cmd_LowAddr,u8ReadBuffer,256);
#if 1
{
WORD inx;
printf("ReadData --------- \n");
for(inx = 0; inx < 256; inx++)
{
printf("0x%02x, ", u8ReadBuffer[inx]);
}
}
#endif
}
when i chenge value of unsigned int u16Cmd_LowAddr = 0xD000;
into 0xE000, value shows only 0x00
i also tried 0xf00, but that didnt help neither
A typical I2C EEPROM does not allow writing more than one page at a time. So, if your EEPROM has 256-byte pages and you need to write more than 256 bytes, you need to perform multiple writes.
Here is an excerpt from an ST EEPROM datasheet:
The Page Write mode allows up to 256 byte to be written in a single
Write cycle, provided that they are all located in the same page in
the memory: that is, the most significant memory address bits, b16-b8,
are the same. If more bytes are sent than will fit up to the end of
the page, a “roll-over” occurs, i.e. the bytes exceeding the page end
are written on the same page, from location 0.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have an inbuilt algorithm in my application. Whenever I run the algorithm, it saves that exact run time in the database. For example, if I run the algorithm at 11.00, it saves that time. And again if I run at 11.05, it saves 11.05 in the database.
I want to detect the number of times it Ran. So that once it runs for 5 times, I need to do some action like changing the values and reset the counter to 0. So that when it reaches 5 iterations, again I should reset the counter.
I am a beginner. It will be helpful if you could help me with the syntax.
MAIN
{
int temp1, temp2, flag = 0, max = 5;
temp1 = GET_INT_VALUE(8,1,84,1,0);
if flag = 0;
while(1)
{
if (templ == temp2)
flag++;
else
flag = 0;
if (flag == max)
{
//sprintf(Message,"SE value is %d",temp2);
PRINTOUT("Message");
flag = 0;
break;
}
}
}
END
The best way is to use a static local variable, like this:
void foo(void) {
static int counter = 0;
counter++;
if(counter > 5) {
counter = 0;
/* Do something every fifth time */
}
}
Note that you can't use a normal local variable (e.g. int counter = 0;) because its contents will be lost when the function returns. The static makes it work more like a global variable (so its value isn't lost when the function returns).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Please excuse me for asking this, because I know the code I'm gonna give you is wrong. Being a newbie I am not able to find the fault. Please help me correct the question and give a solution as well. Again I'm sorry to bother with this simple problem. Tomorrow is my exm in C so i'm kinda desperate. :(
Q: What will be the output of the program?
First let me show you how I find the code first:
#include<stdio.h>
int funct l(int n){
if (n>3)
return int funct(n-3)));
}
main() {
int n= 10;
printf("%d", funct l (n));
}
Then I thought i'd correct it. Then I cleaned up the code as far as i can. Then the code came to this:
#include<stdio.h>
int funct(int n){
if (n>3){
return funct(n-3);
}
}
main() {
int n= 10;
printf("%d", funct(n));
}
still it doesn't give proper answer (though I don't know what it'll show). It is either 1 or 2 and process returned 1 (0*1) is showing at the last line.
Please help me out!
Your funct function doesn't always return a value. This means that it could return anything. Try this:
int funct(int n) {
if (n > 3)
return funct(n - 3);
return n;
}
Here is the call stack when n = 10
funct(n = 10)
funct(n = 7)
funct(n = 4)
funct(n = 1)
return 1
return 1
return 1
return 1
Here is the call stack when n = 11
funct(n = 11)
funct(n = 8)
funct(n = 5)
funct(n = 2)
return 2
return 2
return 2
return 2