Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs

Dashboard
Notifications
Mark all as read
Q&A

Tips for golfing using C

+2
−0

C is a language I use most apart from Python and as someone who likes code golf challenges, what tips are there to golf in C?

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

3 answers

+1
−0

Assign ints before main(){}

This is a combination of 2 golfing tricks. It's possible to write a program as just main(){}, though it will send a warning, not an error though, so it's still safe to run.

A cool trick with using this is assigning values meant to be ints which you can assign inside main anyway.

Try changing the number value here, it works!

i;main(){i=0;printf("%i",i);}

Try it online!

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

No need for i=0. (1 comment)
+1
−0

For the sake of code golf, you first need to decide if you wish to compete in strictly conforming ("real") C, in which case you can't rely on non-standard extensions, poorly-defined behavior or obsolete features.

Or you can compete in non-standard extensions (gcc/GNU etc), when whatever binary the compiler lets through with default settings is fair game - including those that may be abusing poorly-defined behavior.

List of tricks below:

  • Format of main()
    In strictly conforming hosted C, the form int main() is the most compact. Empty parenthesis is obsolete style but it has not yet been formally withdrawn. Alternatively two parameters can be used, normally named argv and argc though C allows us to rename them. In conforming C, we may not change their types however, so the most compact conforming version is:

    int main(int c,char**v)
    

    (Or use compatible types.) main(c,v) is however not conforming.

    In conforming freestanding C, other forms of main() may be used, but that's for embedded systems and not likely applicable for code golf.

    In non-conforming/gcc extensions, old C90 style main() works.

    Note that return 0; is no longer necessary in main() as from C99 - omitting it is well-defined.

  • Format of functions. Non-conforming K&R style functions are still supported by most compilers, for example:

    f(a,b)int a;char b; 
    

    This can be handy when you need to declare parameters and local variables with the same type.

  • Abuse static storage duration. Variables declared at file scope have static storage duration and are therefore guaranteed by the standard to be zero-initialized, saving the need to do such in code.

  • Abuse C90 implicit int. In C90 and non-conforming gcc extensions you can declare a variable as x; and you get an int. Similarly, in C90 functions that declare no return type were assumed to return int.

  • Omit include files. While not allowed in strict C, non-standard gcc allows to omit all #include.

  • Always use for loops. for(;;) is the most compact form. The first clause can be used for variable declarations, which is handy since you have to leave a semicolon there anyway. The 2nd and 3rd clauses can contain pretty much any code, such as a long list separated by , operator. In many cases you can place the whole program there and then end the line with ;, no need for a loop body with {}.

  • Use recursion instead of loops. Recursion can save a lot of overhead code, in case the equivalent loop has a suitable exit condition that needs to be there no matter.

  • Use ?: instead of if-else. It is far more compact and can be used to write long nested expressions in compact ways.

  • && short circuit instead of if. For example if(foo)bar(); can often be written as foo&&bar();.

  • Mix ++ and -- with other expressions. Contrary to good programming practice, this can save characters. For example for(;;i--)printf("%d",a[i]); could be written as for(;;)printf("%d",a[i--]);. Experiment with prefix and postfix versions too. Big chance that you end up with a non-conforming solution though.

  • ! is generally handy, for example when converting a non-zero value to 1, or to get boolean 1/0 out of expressions.

  • Use bitwise operators when possible. && and || can sometimes be replaced with & and |.

  • ^ xor instead of !=.

  • sizeof doesn't need parenthesis if the operand is an expression. Don't do sizeof(expr), always do sizeof expr.

  • Pointer arithmetic instead of array indexing. arr+n not arr[n].

  • Use # pre-processor stringification. If you can afford a #define then everything inside it can be turned to string literals, which is handy if you have to repeat a lot of strings. Pre-processor string concatenation is also handy: "foo" "bar" will create "foobar".

  • int can often be used instead of char for storing characters.

  • Integer constants are more effective than character ones. Use char ch=32; not char ch=' '.

  • Use binary arithmetic instead of larger numbers. ~0 instead of 4294967296. 1<<30 instead of 0x40000000. And so on.

  • X-macros are handy for avoiding repetition. Particularly when listing data. One example here: https://codegolf.codidact.com/posts/279820/279856#answer-279856

  • Abuse the poor type system and endianess when printing strings. Wildly non-conforming: int x=65; puts(&x); This prints the null terminated string "A", since puts treats the raw binary on a 32 bit int little endian machine as hex 41 00 00 00. This can also be handy for integer to string conversions where you already have the integer in memory.

  • Use puts when possible. It is compact and saves you from printf with the burdensome format string. It also prints new line implicitly. And I've seen some other clever uses like malloc(puts(s)) instead of malloc(strlen(s)+1).

  • Use VLA. Avoid malloc, use VLA instead. int x[n]; beats int*x=malloc(n);

  • Use evil non-standard libs. Some compilers support gets,putch and similar compact functions as non-standard extensions without the need to include special headers.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+0
−0

Abuse (as few) libraries (as possible)

We don't want to use too much libraries when playing challenges. Sometimes, libraries aren't used at all in some answers in C.

What if we want to shorten some code? Functions do the trick, specifically built-ins. It's specified you don't have to apply the byte count from accessing libraries, and with this in our advantage, we can use libraries, but it's better if we use only 1 or a few.

Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!