What am I doing wrong with this for loop in C? - c

I'm trying to implement the below code in a for loop, to avoid needing to have every XOR term written out separately.
unsigned int check_0 = P0^en[2]^en[4]^en[6]^en[8]^en[10]^en[12]^en[14]^en[16]^en[18]^en[20]^en[22]^en[24]^en[26]^en[28]^en[30];
This is what I've written, but it doesn't work. Can someone please let me know what I'm doing wrong?
unsigned int check_0z = P0;
unsigned int check_0 = 0;
int i = 2;
for (i = 2; i > 30; i += 2){
check_0 = check_0z^en[i];
check_0z = check_0;
}

Related

Problem organizing a data set chronologically

I'm here asking for your help, not because I have an error, but simply because of this solution that in my head seemed quite credible despite not working.
I basically have a structure to make an appointment and I created a variable of this temporary structure to change the values ​​so that they are in ascending order, however when I show the query table in this case, but the queries appear in the order I registered them in the program.
My Struct:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
My function that should order the values:
void organizarAgenda(int membroEscolhido, consulta agenda[][50][50], int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i, j;
boolean substituir;
consulta temp;
for (i = 0; i < nAgendas[membroEscolhido]; i++)
{
for (j = 0; j < nAgendas[membroEscolhido]; j++)
if (agenda[j][membroEscolhido][clinicaSelecionada].ano > agenda[i][membroEscolhido][clinicaSelecionada].ano)
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes > agenda[i][membroEscolhido][clinicaSelecionada].mes))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia > agenda[i][membroEscolhido][clinicaSelecionada].dia))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia == agenda[i][membroEscolhido][clinicaSelecionada].dia
&& agenda[j][membroEscolhido][clinicaSelecionada].horasInicio >= agenda[i][membroEscolhido][clinicaSelecionada].horasInicio))
substituir = true;
if (substituir == true)
{
//Igualar a variavel temporario á variável agenda em i
temp.ano = agenda[i][membroEscolhido][clinicaSelecionada].ano;
temp.mes = agenda[i][membroEscolhido][clinicaSelecionada].mes;
temp.dia = agenda[i][membroEscolhido][clinicaSelecionada].dia;
temp.horasInicio = agenda[i][membroEscolhido][clinicaSelecionada].horasInicio;
temp.minutosInicio = agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio;
temp.horasFim = agenda[i][membroEscolhido][clinicaSelecionada].horasFim;
temp.minutosFim = agenda[i][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em i á variável agenda em j
agenda[i][membroEscolhido][clinicaSelecionada].ano = agenda[j][membroEscolhido][clinicaSelecionada].ano;
agenda[i][membroEscolhido][clinicaSelecionada].mes = agenda[j][membroEscolhido][clinicaSelecionada].mes;
agenda[i][membroEscolhido][clinicaSelecionada].dia = agenda[j][membroEscolhido][clinicaSelecionada].dia;
agenda[i][membroEscolhido][clinicaSelecionada].horasInicio = agenda[j][membroEscolhido][clinicaSelecionada].horasInicio;
agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio = agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio;
agenda[i][membroEscolhido][clinicaSelecionada].horasFim = agenda[j][membroEscolhido][clinicaSelecionada].horasFim;
agenda[i][membroEscolhido][clinicaSelecionada].minutosFim = agenda[j][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em j á variavel temporaria
agenda[j][membroEscolhido][clinicaSelecionada].ano = temp.ano;
agenda[j][membroEscolhido][clinicaSelecionada].mes = temp.mes;
agenda[j][membroEscolhido][clinicaSelecionada].dia = temp.dia;
agenda[j][membroEscolhido][clinicaSelecionada].horasInicio = temp.horasInicio;
agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio = temp.minutosInicio;
agenda[j][membroEscolhido][clinicaSelecionada].horasFim = temp.horasFim;
agenda[j][membroEscolhido][clinicaSelecionada].minutosFim = temp.minutosFim;
}
}
Thank you all in advance!
substituir is unitialized. You need to set it to false immediately after the for statement for j.
Your for loop for j is missing a trailing { so it will only iterate over the first if and not the others [as you would probably like]
As I mentioned in my comment, simplify [please ;-)]. Use pointers to simplify the code.
Your indexing is quite complex, so I can only guess at things.
I changed the comparison logic to something I understand.
Here's a simplified version. I just coded it, so it may not compile. But, it should give you some ideas how to proceed:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
void
organizarAgenda(int membroEscolhido, consulta agenda[][50][50],
int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i;
int j;
int lim = nAgendas[membroEscolhido];
int dif;
consulta temp;
for (i = 0; i < lim; i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = 0; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
do {
dif = iptr->ano - jptr->ano;
if (dif)
break;
dif = iptr->mes - jptr->mes;
if (dif)
break;
dif = iptr->dia - jptr->dia;
if (dif)
break;
} while (0);
if (dif <= 0)
continue;
temp = *iptr;
*iptr = *jptr;
*jptr = temp;
}
}
}
I'm [still] guessing but I think you can get a [significant] speedup by changing the for loop for j.
And, I think the for loop for i goes one too far.
So, consider:
for (i = 0; i < (lim - 1); i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = i + 1; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
UPDATE:
I didn't understand how a 3d array with only a 2d array assignment works int lim = nAgendas[membroEscolhido];
The value of nAgendas[membroEscolhido] is invariant across the function, so it can be "cached". I did this to simplify the code [mostly] but it also can help the compiler generate more efficient code.
I didn't notice the (-) in the middle of this line, and the -> works because it is a pointer pointing to the struct, right?
Right. The arrow operator (->) is a very powerful way to access individual struct members if you have a pointer to the given struct instance.
Note that the compiler's optimizer might be able to see that all the variables of the form: array[x][y][z].whatever could be reduced.
But, when we use intermediate pointers we're giving it a [better] clue as to what we want. And, the code is more readable by humans, so it has two good reasons to do it.
I don't understand why you put while (0)
This is a bit of a trick [of mine] to replace an if/else ladder with something that is cleaner.
It forms a "once through" loop. It would be the equivalent of:
while (1) {
if (something)
break;
if (something_else)
break;
break; // make the loop execute _only_ once
}
For a more detailed explanation, see my answer: About the exclusiveness of the cases of an if block

C conversion of signed int as binary to long

I have a function which converts an integer to its binary representation and its stored in a long variable. My problem is that my function converts only positive integers so I need to implement a new function which will be slightly changed to do just that. I still need to store the bin. rep. in a long variable because that depends on the other features. Is there a way?
My function which successfully converts only positive integers:
long convertToBin(int decn)
{
long binn = 0;
long rem;
long a = 1;
while(decn != 0)
{
rem = decn % 2;
binn = binn + rem * a;
a = a * 10;
decn = decn / 2;
}
return binn;
}
I've tried it like this, but there is something wrong - doesn't work...
long negConvertToBin(int decn)
{
long binn = 0;
decn = abs(decn);
decn = decn - 1;
decn = ~decn;
long rem;
long a = 1;
while(decn != 0)
{
rem = decn % 2;
binn = binn + rem * a;
a = a * 10;
decn = decn / 2;
}
return binn;
}
Is there a way?
Consider code re-use since you have a working convertToBin() for positive values.
long NegAndPosConvertToBin(int decn) {
if (decn < 0) return -convertToBin(-decn);
return convertToBin(decn);
}
If OP still wants a stand-alone long negConvertToBin(int decn), then
long negConvertToBin(int decn) {
decn = -decn;
// same body as convertToBin() without the return
return -binn;
}
As well commented by #Some programmer dude, OP's approach has limited useful int range as overflow occur with large values.
For a textual conversion for all int to various bases including 2, see char* itostr(char *dest, size_t size, int a, int base)
i can't comment but sprintf function do works for you :
#include <stdio.h>
int main ( void )
{
char temp[128] ;
int num = -1 ;
sprintf ( temp , "%x" , num );
puts ( temp ) ;
return 0 ;
}

Order array of struct by one chosen attribute in C

I'm having trouble while ordering an array of a struct that contains 3 infos types. I want to order using one of the info, then organize the other 2 infos, but I'm using heapsort and don't know how I would change the code to automatically reorganize. There is any logical hint that would help me? here's the struct
typedef struct{
int orig;
int dest;
float cost;
}infos;
thanks. i can add any info that help you people help me!
[EDIT]
void build ( Armaz x[], int n ){
int i;
float val;
int s;
int f;
for (i = 1; i<n; i++){
val = x[i].cost;
s = i;
f = (s-1)/2;
while (s>0 && x[f].cost<val){
x[s].cost = x[f].cost;
s = f;
f = (s-1) / 2;
}
x[s].cost = val;
}
}
void heapsort (infos x[], int n){
build(x,n);
int i;
int s;
int f;
float vali ;
for (i = n - 1 ; i > 0 ; i--){
vali = x[i].cost;
x[i].cost = x[0].cost;
f = 0 ;
if (i == 1){
s = -1;
}
else s = 1;
if ( i > 2 && x[2].cost > x[1].cost) s = 2 ;
while ( s >= 0 && vali < x[s].cost){
x[f].cost = x[s].cost;
f = s;
s = 2 * f + 1;
if ( s + 1 <= i - 1 && x[s].cost < x[s + 1].cost ) s++;
if (s > i-1) s = -1;
}
x[f].cost = vali;
}
}
Even if you implement your own sorting functions, I recommend you take a closer look at how the standard qsort function works.
In short: It has an argument that is a pointer to a function used for comparison. That function receives pointers to two "objects" that should be compared, and can do whatever it wants to compare the two "objects". That means one could have three different comparison functions, one for each member of your structure, and pass the appropriate one when needed.

Difference between two C snippets

I am at a loss to explain why these two C snippets do not behave the same way. I am trying to serialize two structs, eh and ah, as a single buffer of bytes (uint8_t). The first code block works, the second does not. I can't figure out the difference. If anyone can explain it to me it would be greatly appreciated.
Block 1:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
uint8_t *eh_ptr = (uint8_t*)&eh;
for (int i = 0; i < sizeof(eh); i++)
{
arp_reply_buf[i] = eh_ptr[i];
}
uint8_t *ah_ptr = (uint8_t*)&ah;
int index = 0;
for (int i = sizeof(eh); i < (sizeof(eh) + sizeof(ah)); i++)
{
arp_reply_buf[i] = ah_ptr[index++];
}
Block 2:
uint8_t arp_reply_buf[sizeof(eh) + sizeof(ah)];
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;
In the second example you only set the values in two indexes:
arp_reply_buf[0]:
arp_reply_buf[0] = *(uint8_t *)&eh;
arp_reply_buf[sizeof(eh)]:
arp_reply_buf[sizeof(eh)] = *(uint8_t *)&ah;

Problem with FFTW2 routine in C

I'm currently working with the FFTW2 (Fastest Fourier Transform in the West) library, and after writing a successful routine in Fortran, I am moving on to C. However, I'm having some trouble with data assigning when I try to input the data to transform (ie, the values of sin(x)). Currently, my code is:
#include <stdio.h>
#include <fftw.h>
#include <math.h>
#include <complex.h>
void compute_fft(){
int i;
const int n[8];
fftw_complex in[8];
fftwnd_plan p;
in[0]->re = 0;
in[1]->re = (sqrt(2)/2);
in[2]->re = 1;
in[3]->re = (sqrt(2)/2);
in[4]->re = 0;
in[5]->re = -(sqrt(2)/2);
in[6]->re = -1;
in[7]->re = -(sqrt(2)/2);
for(i = 0; i < 8; i++){
(in[i])->im = 0;
}
p = fftwnd_create_plan(8, n, FFTW_FORWARD, FFTW_ESIMATE | FFTW_IN_PLACE);
fftwnd_one(p, &in[0], NULL);
fftwnd_destroy_plan(p);
printf("Sin\n");
for(i = 0; i < 8; i++){
printf("%d\n", n[i]);
}
}
I've been using this http://fftw.org/fftw2_doc/ link for documentation/tutorial purposes, and currently my error is "invalid type argument of a->a (have afftw_complexa)", and the 'a' characters on either side of the -> and fftw_complex have carats above them. I'm using basically the same pattern that worked when I wrote this in Fortran, and I seem to be following the tutorial, it's really just this assignment here that I am messing up the syntax on. For the record, the compiler I am using is nvcc, if it makes a difference (I previously tried gcc). If anyone here has every used FFTW2 in C before, could you help correct my mistake? Thank you!
It might be because of your array "in" which is a array of fftw_complex so instead of using in[0]->re = 0 you should use it as in[0].re = 0. Unless fftw_complex is again typedefined to some array.
fftw_complex in[8];
in[0].re = 0;
in[1].re = (sqrt(2)/2);
in[2].re = 1;
in[3].re = (sqrt(2)/2);
in[4].re = 0;
in[5].re = -(sqrt(2)/2);
in[6].re = -1;
in[7].re = -(sqrt(2)/2);
Since ffwt_complex is an double[2] being the first dimension([0]) for the real data and the second ([1]) for the imaginary data, a safe solution is:
in[0][0] = 0;
in[1][0] = (sqrt(2)/2);
in[2][0] = 1;
in[3][0] = (sqrt(2)/2);
in[4][0] = 0;
in[5][0] = -(sqrt(2)/2);
in[6][0] = -1;
in[7][0] = -(sqrt(2)/2);
for(i = 0; i < 8; i++){
in[i][1] = 0;
}

Resources