In my code I often have a for loop for doing a single operation n times. E.g:
// Wait for settle
int delayLoop = 0;
int count = 0;
for(delayLoop = 0; delayLoop < count; delayLoop++) {
__NOP(); // operation to do
}
At first I wanted to make this as an function....but then I realized I do not know how to pass in the operations as a function argument.
In the above example the __NOP() is itself a macro that expands to:
__ASM volatile ("nop")
So how can I come up with a macro that I can call like this:
DO_LOOP(10, __NOP)
and what if I need to do more operations? e.g.
DO_LOOP(8, __NOP, myFunction(arg1))
that would expand to:
for(int i = 0; i < 8; i++) {
__NOP;
myFunction(arg1);
}
#define DO_LOOP(x, ...) for (int i = 0; i < x; ++i) { __VA_ARGS__; }
void f1() { printf("test\n"); }
void f2() { printf("a\n"); }
int main()
{
DO_LOOP(10, f1(), f2());
return 0;
}
gcc -E test.c:
void f1() { printf("test\n"); }
void f2() { printf("a\n"); }
int main()
{
for (int i = 0; i < 10; ++i) { f1(), f2(); };
return 0;
}
This doesn't work with inline assembly though. You can do something like:
#define DO2(x, a, b) for (int i = 0; i < x; ++i) { a; b;}
and use:
DO2(10, __NOP(), f1());
Related
This question doesn't require any initial explanation, other that to show the examples.
Why does this work (prints the contents of array a):
#include <stdio.h>
int a[100];
void check(int **b)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", b[0][i]);
}
int main()
{
int *arr = a;
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check(&arr);
return 0;
}
and this doesn't (compiles with onlinegdb c compiler, but prints nothing)?
#include <stdio.h>
int a[100];
void check(int **c)
{
int i;
for (i = 0; i < 100; i++)
printf("%d ", c[0][i]);
}
int main()
{
int i;
for (i = 0; i < 100; i++)
{
a[i] = i;
}
check((int**)&a);
return 0;
}
I understand that array is a special data type in C, but shouldn't casting it to a pointer type or assigning it to one be the same? Is there a way to make the second example work without the additional pointer?
Something like
int main(void){
doTenTimes({
printf("Hello World");
});
}
And then the function doTenTimes could execute that block of code 10 times.
You probably don't want to "pass a block of code", but rather to implement the function to suit whatever you need to do:
void doManyTimes(int n)
{
for(int i=0; i<n; i++)
printf("Hello World\n");
}
Alternatively, you could pass a function pointer pointing at a different function, to provide the behavior separately:
typedef void dofunc_t (void);
void print (void)
{
printf("Hello World\n");
}
void doManyTimes(dofunc_t* func, int n)
{
for(int i=0; i<n; i++)
func();
}
// call:
doManyTimes(print,10);
You really can't treat "naked" blocks of code like data in C. Lundin's approach is the best for what you want to do.
However, for completeness' sake, here's an example using a macro (FOR THE LOVE OF GOD NEVER DO THIS):
#include <stdio.h>
/**
* Wrapping in a do...while(0) keeps the compiler from bitching at
* me over the trailing semicolon when I invoke the macro in main.
*/
#define doTenTimes(STMT) do { for (size_t i = 0; i < 10; i++ ) STMT } while( 0 )
int main( void )
{
doTenTimes( { printf( "hello, world\n" ); } );
return 0;
}
After preprocessing we get this:
int main( void )
{
do { for (size_t i = 0; i < 10; i++ ) {printf( "hello, world\n" ); } } while (0);
return 0;
}
It "works", but it's super ugly and made me itch as I wrote it. Don't ever do anything like this.
#include <stdio.h>
void hello(void) {
puts("Hello, World!");
}
void byebye(void) {
puts("Good bye, World!");
}
int main(void) {
void (*work)(void) = hello;
for (int i = 0; i < 10; i++) work();
work = byebye;
for (int i = 0; i < 10; i++) work();
return 0;
}
See code running at https://ideone.com/ivsxxR
void f() {
for (i == 0; i < 6 && i++, i <10; i++)
{
printf("%d", i);
}
}
int main()
{
f();
return 0;
}
Codes Picture
Output
Any tips on how to debug for loops on paper without a computer
In the code, by saying i == 0 (comparison operator) instead of i = 0 (assignment operator), in the successive use, you're using an uninitialized local variable, which has indeterminate value.
That said, the correct version should look like
#include <stdio.h> //header file is needed
void f() {
for (int i = 0; i < 6 && i++, i <10; i++) // define types
{
printf("%d", i);
}
}
int main(void) // correct signature
{
f(); // indent, optional but good
return 0;
}
I'm working on a project that requires somewhat similar functionality to the program below so I've tried to create a simpler program to debug my larger program. The threads I'm creating are returning values that are inconsistent with their expected output but their return values are not random. It almost seems like the threads are returning the values from other threads or that the variable they are returned to ("tmp") is updating.
The expected output should be...
0 1
1 2
#include <stdio.h>
#include <pthread.h>
struct Numbers {
int x;
int y;
};
void *go(void* param)
{
struct Numbers* nums = (struct Numbers*) param;
int sum = nums -> x + nums -> y;
return (void*) sum;
}
int main()
{
int result[2][2];
int tmp;
pthread_t thread[2][2];
int i, j;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
struct Numbers nums;
nums.x = i;
nums.y = j;
pthread_create(&thread[i][j], NULL, go, &nums);
}
}
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
pthread_join(thread[i][j], (void*) &tmp);
result[i][j] = tmp;
}
}
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
printf("%d\t", result[i][j]);
}
printf("\n");
}
return 0;
}
You're passing the address of a variable that probably won't exist once the thread begins executing, or at least will be seen by multiple threads, or is a data race as one thread writes it while the others read it.
A general solution is to dynamically allocate both the arguments and results of your thread, and let the caller and thread communicate that way.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct threadargs {
int x;
int y;
};
struct threadresults {
int sum;
int product;
};
void* threadfunc(void* args_void) {
// Get thread args in usable type.
struct threadargs* args = args_void;
struct threadresults* results = NULL;
//Compute.
int sum = args->x + args->y;
int product = args->x * args->y;
// Return the result.
results = malloc(sizeof(*results));
results->sum = sum;
results->product = product;
free(args);
return results;
}
int main()
{
pthread_t thread[2][2];
struct threadresults* results[2][2] = {0};
int i, j;
for (i = 0;i < 2; ++i) {
for (j = 0; j < 2; ++j) {
struct threadargs* args = malloc(sizeof(*args));
args->x = i;
args->y = j;
pthread_create(&thread[i][j], NULL, threadfunc, args);
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
void* result;
pthread_join(thread[i][j], &result);
results[i][j] = result;
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("sum: %d\tproduct: %d\n",
results[i][j]->sum, results[i][j]->product);
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
free(results[i][j]);
}
}
return 0;
}
This code below is the code for finding the determinant for 3x3 matrix (this code is intended for nxn matrix, but for the sample, I used 3x3), using recursive
The result is working fine, but I wonder what errors in this code make this must be the printf("\n") before calling the sub-function (itself) or else it will return the error 0xc0000fd (stack overflow).
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#define size 3
void trimarray(int**rrayrc,int**rrayout, int dim,int cuti,int cutj)
{
int i, j;
int ti = 0,tj;
for(i = 0; i<dim; i++)
{
tj = 0;
for(j = 0; j< dim; j++)
{
if(!((i==cuti)||(j==cutj)))
{
rrayout[ti][tj] = rrayrc[i][j];
}
if(j!=cutj) {tj++;}
}
if(i!=cuti) {ti++;}
}
}
void initializearray(int** rray,int dim)
{
int i, j;
for(i = 0; i<dim; i++)
{
for(j = 0; j<dim; j++)
{
rray[i][j] = 0;
}
}
}
int det(int** rray, int dim)
{
int i,j;
int cut[dim-1][dim-1];
int* cutp[i];
int mul = 1,sum=0;
if(dim >1)
{
for(i = 0; i<dim-1; i++)
{
cutp[i] = cut[i];
}
initializearray(cutp,dim-1);
for(i = 0; i<dim; i++)
{
printf("\n",dim); //<< Without this the program won't work
trimarray(rray,cutp,dim,0,i);
sum+=det(cutp,dim-1)*mul*rray[0][i];
mul = 0-mul;
}
return sum;
}
else
{
return rray[0][0];
}
}
int main()
{
int test[size][size] = {2,-3,-2,-6,3,3,-2,-3,-2};
int* testpntr[size];
int i,deter;
for(i = 0; i<size; i++)
{
testpntr[i] = test[i];
}
deter = det(testpntr,size);
printf("[%d]",deter);
getch();
return 0;
}
The answers will be dearly appreciated.
int* cutp[i]; is undefined behavior since i is uninitialized at this stage. You have no idea what is the size of cutp array.