168
\$\begingroup\$

What general tips do you have for golfing in C? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to C (e.g. "remove comments" is not an answer). Please post one tip per answer. Also, please include if your tip applies to C89 and/or C99 and if it only works on certain compilers.

\$\endgroup\$
1
  • 20
    \$\begingroup\$ I think the biggest single-sentence hint is: Read the winning codes submitted to IOCCC. \$\endgroup\$
    – vsz
    Commented May 12, 2012 at 21:23

65 Answers 65

130
\$\begingroup\$

Use bitwise XOR to check for inequality between integers:

if(a^b) instead of if(a!=b) saves 1 character.

\$\endgroup\$
5
  • 87
    \$\begingroup\$ a-b gives you the same effect. \$\endgroup\$
    – ugoren
    Commented Jan 12, 2012 at 16:16
  • 30
    \$\begingroup\$ Similarly you can use a*b instead of a&&b (has different precendence, may or may not be bad). If you know a /= -b (e.g. they are unsigned) then a||b == a+b \$\endgroup\$
    – walpen
    Commented Jun 9, 2012 at 16:35
  • 3
    \$\begingroup\$ better yet combine it with the Elvis Operator ?: (instead of if) : for exemple to just do something if differents: a^b?_diff_:; \$\endgroup\$ Commented Dec 24, 2016 at 8:52
  • 1
    \$\begingroup\$ @OlivierDulac Is there a compiler that accepts an empty ternary if false branch? \$\endgroup\$ Commented May 4, 2018 at 10:50
  • 3
    \$\begingroup\$ @OlivierDulac You can check. From what I know, GCC has a ?: operator which is just equivalent to a ? a : b \$\endgroup\$
    – Chromium
    Commented Jun 22, 2018 at 2:58
96
\$\begingroup\$
  • Abuse main's argument list to declare one or more integer variables:

    main(a){for(;++a<28;)putchar(95+a);}
    

    (answer to The alphabet in programming languages)

    This solution also abuses the fact that a (a.k.a. argc) starts out as 1, provided the program is called with no arguments.

  • Use global variables to initialize things to zero:

    t[52],i;main(c){for(;i<52;)(c=getchar())<11?i+=26:t[i+c-97]++;
    for(i=27;--i&&t[i-1]==t[i+25];);puts(i?"false":"true");}
    

    (answer to Anagram Code Golf!)

\$\endgroup\$
2
  • \$\begingroup\$ There are no data types defined for variables, no return type of main function. Is this valid C syntax? \$\endgroup\$
    – pavi2410
    Commented Jan 7, 2020 at 10:23
  • 7
    \$\begingroup\$ @Pavitra : yes, this is commonly known as the "pre-ANSI" or "K&R" C variant. A variable without a type declared explicitly is an int. This has since been deprecated and all variables and functions are required to be declared with a type. \$\endgroup\$ Commented Jan 23, 2020 at 20:44
80
\$\begingroup\$

Avoid catastrophic function-argument type declarations

If you're declaring a function where all five arguments are ints, then life is good. you can simply write

f(a,b,c,d,e){

But suppose d needs to be a char, or even an int*. Then you're screwed! If one parameter is preceded by a type, all of them must be:

f(int a,int b,int c,int*d,int e){

But wait! There is a way around this disastrous explosion of useless characters. It goes like this:

f(a,b,c,d,e) int *d; {

This even saves on a standard main declaration if you need to use the command-line arguments:

main(c,v)char**v;{

is two bytes shorter than

main(int c,char**v){

I was surprised to discover this, as I have not so far encountered it on PPCG.

\$\endgroup\$
7
  • 13
    \$\begingroup\$ Why on Earth does that work?? \$\endgroup\$
    – N. Virgo
    Commented Oct 24, 2014 at 8:41
  • 41
    \$\begingroup\$ Apparently this is called K&R style and it precedes ANSI C by a decade. \$\endgroup\$
    – Dennis
    Commented Oct 24, 2014 at 13:59
  • 3
    \$\begingroup\$ Note that using K&R features and newer (say '99) features together nay or may not be possible. Depends on your compiler. \$\endgroup\$ Commented May 17, 2015 at 17:47
  • 8
    \$\begingroup\$ @dmckee is right. C99 does not allow implicit int, so you have to use -std=gnu99 and now you're not portable. In clc-speak, you're not even writing "C" code per se, but "Gnu99-C". 'Round here we mostly ignore that, but it's good to mention it if you post code that is compiler-specific. Sometimes people actually do download and execute these programs of ours. :) \$\endgroup\$ Commented Jul 13, 2015 at 20:58
  • 2
    \$\begingroup\$ @luserdroog: You can use -std=c89 to tell gcc or clang to compile your code according to that older standard, which does allow implicit int with only a warning. \$\endgroup\$ Commented Jun 14, 2018 at 15:09
76
\$\begingroup\$

The comma operator can be used to execute multiple expressions in a single block while avoiding braces:

main(){                                                                                     
                                                                                            
int i = 0;                                                                                  
int j = 1;                                                                                  
if(1)                                                                                       
    i=j,j+=1,printf("%d %d\n",i,j); // multiple expressions are all executed                                                  
else                                                                                        
    printf("failed\n");                                                                     
                                                                                            
}

Outputs: 1 2

\$\endgroup\$
3
  • \$\begingroup\$ Doesn't work if one of the statements is break. \$\endgroup\$ Commented Apr 8, 2017 at 2:46
  • 22
    \$\begingroup\$ @MaxLawnboy because break is a statement, and this answer is talking about expressions. \$\endgroup\$
    – Maya
    Commented Feb 5, 2018 at 16:25
  • \$\begingroup\$ @Maya Well, only since Claudia edited the intro text to say "expressions". (And missed the comment, which still says "statements". So now the answer's actually contradictory.) But in Casey's original version, "statements" was used consistently. \$\endgroup\$
    – FeRD
    Commented Jul 10 at 5:35
47
\$\begingroup\$

Instead of >= and <= you can simply use integer division (/) when the compared values are above zero, which saves one character. For example:

putchar(c/32&&126/c?c:46); //Prints the character, but if it is unprintable print "."

Which is of course still shrinkable, using for example just > and ^ (a smart way to avoid writing && or || in some cases).

putchar(c>31^c>126?c:46);

The integer division trick is for example useful to decide whether a number is less than 100, as this saves a character:

a<100 vs 99/a

This is also good in cases when higher precedence is needed.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can write putchar(c>31&c<127?c:46); \$\endgroup\$
    – Jin X
    Commented Feb 24, 2019 at 19:33
47
+250
\$\begingroup\$

Use lambdas (unportable)

Instead of

f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);

or (gcc only)

qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));

or (clang with blocks support)

qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});

try something like

qsort(a,b,4,"\x8b\7+\6\xc3");

...where the string literal contains the machine language instructions of your "lambda" function (conforming to all platform ABI requirements).

This works in environments in which string constants are marked executable. By default this is true in Linux and OSX but not Windows.

One silly way to learn to write your own "lambda" functions is to write the function in C, compile it, inspect it with something like objdump -D and copy the corresponding hex code into a string. For example,

int f(int*a, int*b){return *a-*b;}

...when compiled with gcc -Os -c for a Linux x86_64 target generates something like

0:   8b 07                   mov    (%rdi),%eax
2:   2b 06                   sub    (%rsi),%eax
4:   c3                      retq

MD XF wrote a bash script that may assist in the writing of simple "lambda" functions.

Edit: This technique was previously published by Shinichiro Hamaji in this document.

GNU CC goto:

You can call these "lambda functions" directly but if the code you're calling doesn't take parameters and isn't going to return, you can use goto to save a few bytes. So instead of

((int(*)())L"ﻫ")();

or (if your environment doesn't have Arabic glyphs)

((int(*)())L"\xfeeb")();

Try

goto*&L"ﻫ";

or

goto*&L"\xfeeb";

In this example, eb fe is x86 machine language for something like for(;;); and is a simple example of something that doesn't take parameters and isn't going to return :-)

It turns out you can goto code that returns to a calling parent.

#include<stdio.h>
int f(int a){
 if(!a)return 1;
 goto*&L"\xc3c031"; // return 0;
 return 2; // never gets here
}
int main(){
 printf("f(0)=%d f(1)=%d\n",f(0),f(1));
}

The above example (might compile and run on Linux with gcc -O) is sensitive to the stack layout.

EDIT: Depending on your toolchain, you may have to use the -zexecstack (for gcc) or -Wl,-z,execstack (for clang) compile flag.

If it isn't immediately apparent, this answer was mainly written for the lols. I take no responsibility for better or worse golfing or adverse psychological outcomes from reading this.

\$\endgroup\$
1
  • 6
    \$\begingroup\$ I've just written a script to read parts of a C function from standard in and print a C lambda. Might be worth mentioning in your answer, might just be nice for you to see since you taught me to do this in the first place. \$\endgroup\$
    – MD XF
    Commented Feb 3, 2018 at 1:24
46
\$\begingroup\$

Certain compilers, such as GCC, allow you to omit basic #includes, param, and return types for main.

The following is a valid C89 and C99 program that compiles (with warnings) with GCC:

main(i) { printf("%d", i); }

Notice that the #include for stdio.h is missing, the return type for main is missing, and the type declaration for i is missing.

\$\endgroup\$
3
  • 23
    \$\begingroup\$ Technically it's not valid according to standards as main accepts zero or two parameters, not one. Not that anyone cares in code golf. \$\endgroup\$
    – null
    Commented Jan 2, 2014 at 22:24
  • 1
    \$\begingroup\$ Calling printf() (or any variadic function) without a prototype causes undefined behaviour. GCC does not compile standard C by default. If you invoke gcc in C89 mode (gcc -ansi -pedantic) or C99 mode (gcc -std=c99 -pedantic), you will get quite a few complaints, at least in the latter case. \$\endgroup\$ Commented Oct 27, 2014 at 13:31
  • 1
    \$\begingroup\$ @NisseEngström: the calling conventions on mainstream C implementations make it safe to call variadic functions without prototypes. So most C implementations do define the behaviour. \$\endgroup\$ Commented Jun 14, 2018 at 15:12
40
\$\begingroup\$

The ternary conditional operator ?: can often be used as a stand in for simple if--else statements at considerable savings.

Unlike the c++ equivalent the operator does not formally yield an lvalue, but some compilers (notably gcc) will let you get away with it, which is a nice bonus.

\$\endgroup\$
5
  • \$\begingroup\$ Addition: If you only need an if, but not an else then the ternary can still be useful. \$\endgroup\$
    – Casey
    Commented Apr 27, 2011 at 20:29
  • 14
    \$\begingroup\$ && and || can also be used: if(x==3)f() becomes with your suggestion x==3?f():0, and can be further improved to x==3&&f(). But be careful with operator precedence - if f() is replaced with y=1, then the && solution requires an extra set of parenthesis. \$\endgroup\$
    – ugoren
    Commented Jan 12, 2012 at 16:20
  • 1
    \$\begingroup\$ I'd never realized that gcc's ?: yields an lvalue. Can I use that in production code? lol \$\endgroup\$ Commented Jan 12, 2012 at 19:55
  • 8
    \$\begingroup\$ @ugoren: x==3&&f() can be further golfed to x^3||f() \$\endgroup\$
    – fgrieu
    Commented Dec 26, 2012 at 12:04
  • 1
    \$\begingroup\$ @fgrieu, yes, though it's not exactly the topic here (this answer suggests it). \$\endgroup\$
    – ugoren
    Commented Dec 26, 2012 at 17:25
35
\$\begingroup\$

http://graphics.stanford.edu/~seander/bithacks.html

Bits are nice.

~-x = x - 1
-~x = x + 1

But with different precedences, and don't change x like ++ and --. Also you can use this in really specific cases: ~9 is shorter than -10.

if(!(x&y)) x | y == x ^ y == x + y
if(!(~x&y)) x ^ y == x - y

That's more esoteric, but I've had occassion to use it. If you don't care about short-circuiting

x*y == x && y
if(x!=-y) x+y == x || y

Also:

if(x>0 && y>0) x/y == x>=y   
\$\endgroup\$
2
  • 8
    \$\begingroup\$ The last tip ((x/y) == (x>=y)) is really useful. \$\endgroup\$
    – ugoren
    Commented Sep 6, 2012 at 9:11
  • \$\begingroup\$ Some of these don't work on my machine (I guess because these hacks largely rely on "undefined" behavior) \$\endgroup\$
    – AnnoyinC
    Commented Jan 20, 2021 at 17:01
31
\$\begingroup\$

Define parameters instead of variables.

f(x){int y=x+1;...}

f(x,y){y=x+1;...}

You don't need to actually pass the second parameter.

Also, you can use operator precedence to save parenthesis.
For example, (x+y)*2 can become x+y<<1.

\$\endgroup\$
3
  • \$\begingroup\$ Or just x+y*2, saving yet another char. \$\endgroup\$ Commented Feb 2, 2014 at 8:29
  • 9
    \$\begingroup\$ @B1KMusic, x+y*2 isn't the same, due to operator precedence. \$\endgroup\$
    – ugoren
    Commented Feb 2, 2014 at 12:13
  • 1
    \$\begingroup\$ Right, lol. That would be x+(y*2). I was fixated on the x+y<<1 example, assuming it was being evaluated as x+(y<<1), and suggested the *2 instead. I didn't know bitshift operations were evaluated as e.g. (x+y)<<2 \$\endgroup\$ Commented Feb 3, 2014 at 2:46
28
\$\begingroup\$

Use cursors instead of pointers. Snag the brk() at the beginning and use it as a base-pointer.

char*m=brk();

Then make a #define for memory access.

#define M [m]

M becomes a postfix * applied to integers. (The old a[x] == x[a] trick.)

But, there's more! Then you can have pointer args and returns in functions that are shorter than macros (especially if you abbreviate 'return'):

f(x){return x M;} //implicit ints, but they work like pointers
#define f(x) (x M)

To make a cursor from a pointer, you subtract the base-pointer, yielding a ptrdiff_t, which truncates into an int, losses is yer biz.

int p = sbrk(sizeof(whatever)) - m;
strcpy(m+p, "hello world");

This technique is used in my answer to Write an interpreter for the untyped lambda calculus.

\$\endgroup\$
25
\$\begingroup\$

The ternary operator ?: is unusual in that it has two separate pieces. Because of this, it provides a bit of a loophole to standard operator precedence rules. This can be useful for avoiding parentheses.

Take the following example:

if (t()) a = b, b = 0;  /* 15 chars */

The usual golfing approach is to replace the if with &&, but because of the low precedence of the comma operator, you need an extra pair of parentheses:

t() && (a = b, b = 0);  /* still 15 chars */

The middle section of the ternary operator doesn't need parentheses, though:

t() ? a = b, b = 0 : 0;  /* 14 chars */

Similar comments apply to array subscripts.

\$\endgroup\$
4
  • 10
    \$\begingroup\$ In this example, b-=a=b is even shorter. The ?: trick is still helpful, -= because also has low preference. \$\endgroup\$
    – ugoren
    Commented May 8, 2012 at 7:30
  • \$\begingroup\$ Good point; my example was needlessly complex. \$\endgroup\$
    – breadbox
    Commented May 8, 2012 at 8:54
  • \$\begingroup\$ Another point is that sometimes you want to flip the condition: for x>0||(y=3), x>0?0:(y=3) is useless, but x<1?y=3:0 does the job. \$\endgroup\$
    – ugoren
    Commented May 8, 2012 at 10:44
  • \$\begingroup\$ both clang and gcc allow for an empty true case in the ternary. If omitted, its value is the value of the condition. For example, x>5?:y=1 \$\endgroup\$ Commented Apr 9, 2019 at 4:56
25
\$\begingroup\$

Any part of your code that repeats several times is a candidate for replacement with the pre-processor.

#define R return

is a very common use case if you code involves more than a couple of functions. Other longish keywords like while, double, switch, and case are also candidates; as well as anything that is idomatic in your code.

I generally reserve uppercase character for this purpose.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ A shorter replacement would be -DR=return. Note that if you include certain characters, it may become necessary to have single or double quotes around the define -DP='puts("hello")'. \$\endgroup\$
    – user77406
    Commented Jul 25, 2018 at 18:29
23
\$\begingroup\$

Since usually EOF == -1, use the bitwise NOT operator to check for EOF: while(~(c=getchar())) or while(c=getchar()+1) and modify value of c at every place

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't know C well enough, but wouldn't while(1+c=getchar()) work? \$\endgroup\$ Commented May 4, 2015 at 16:33
  • 8
    \$\begingroup\$ @ɐɔıʇǝɥʇuʎs No. The addition operator + has higher precedence than the assignment operator =, so 1+c=getchar() is equivalent to (1+c)=getchar(), which does not compile because (1+c) is not an lvalue. \$\endgroup\$
    – user12205
    Commented May 19, 2015 at 18:56
23
\$\begingroup\$

If you ever need to output a single newline character (\n), don't use putchar(10), use puts("").

\$\endgroup\$
20
\$\begingroup\$

Reverse Loops

If you can, try to replace

for(int i=0;i<n;i++){...}

with

for(int i=n;i--;){...}
\$\endgroup\$
1
  • \$\begingroup\$ for(;++i<n;){...} is even shorter if u declare i as a function parameter like fn(i) \$\endgroup\$
    – cegprakash
    Commented May 18, 2021 at 6:55
19
\$\begingroup\$

Use for rather than while

Any while can be changed into a for of the same length:

while(*p++)
for(;*p++;)

On its own, that's not golf. But we now have an opportunity to move an immediately-preceding statement into the parens, saving its terminating semicolon. We might also be able to hoist an expression statement from the end of the loop; if the loop contained two statements, we could also save the braces:

a=5;while(*p++){if(p[a])--a;++b;}

for(a=5;*p++;++b)if(p[a])--a;

Even do...while loops should be replaced with for loops. for(;foo,bar,baz;); is shorter than do foo,bar;while(baz);.

\$\endgroup\$
1
  • \$\begingroup\$ The for loop allows up to two statements this way without braces, where the while loop only allows one. You could have avoided the braces in the first example with a comma as follows: a=5;while(*p++)if(p[a])--a,++b; \$\endgroup\$ Commented Mar 21, 2023 at 18:49
18
\$\begingroup\$

If your program is reading or writing on one in each step basis always try to use read and write function instead of getchar() and putchar().

Example (Reverse stdin and place on stdout)

main(_){write(read(0,&_,1)&&main());}

Exercise:Use this technique to get a good score here.

\$\endgroup\$
6
  • \$\begingroup\$ What do you mean by in each step basis ? \$\endgroup\$
    – Casey
    Commented Apr 26, 2011 at 14:46
  • \$\begingroup\$ Casey: I guess they mean if the program is reading something, operates on it, and writes output. In a streaming manner, so to say. As opposed to an approach where all the input has to be read and handled at once. \$\endgroup\$
    – Joey
    Commented May 27, 2011 at 13:34
  • 10
    \$\begingroup\$ That stack manipulation is gorgeous. \$\endgroup\$ Commented May 21, 2015 at 19:53
  • 1
    \$\begingroup\$ On what ABI and compiler does this work? It does not work on x86-64 (GCC 8.3). \$\endgroup\$
    – Oskar Skog
    Commented Jun 19, 2021 at 16:02
  • 1
    \$\begingroup\$ the last link is dead \$\endgroup\$ Commented Jun 23, 2022 at 15:58
16
\$\begingroup\$

Make use of return values to zero stuff. If you call some function, and that function returns zero under normal conditions, then you can place it in a location where zero is expected. Likewise if you know the function will return non-zero, with the addition of a bang. After all, you don't do proper error handling in a code golf in any case, right?

Examples:

close(fd);foo=0;   →  foo=close(fd);    /* saves two bytes */
putchar(c);bar=0;  →  bar=!putchar(c);  /* saves one byte  */
\$\endgroup\$
15
\$\begingroup\$

Abuse dark corners of array indexing

enter image description here

i[array] desugars into *(i+array), and since + is commutative for pointer+integer too, it is equivalent to *(array+i) and therefore array[i].

It's not very common to see an array indexing expression (whatever)[x] where whatever requires wrapping in parens and x doesn't, but when you see one, you can swap the two positions and write x[whatever] to save two bytes.

A real golfing example.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Another case where I've used this: I had a loop using pointer arithmetic to iterate over argv (named v for brevity), and I only needed the second character of each argv string. The original code used v[0][2] for this (the pointer arithmetic moved v so v[0] was always the current string). Indexing being higher precedence than dereferencing meant *v[2] wasn't an option (it would be (*v)[2], which saves nothing), but 2[*v] worked perfectly and saved two characters while behaving identically to v[0][2]. \$\endgroup\$ Commented Apr 12, 2023 at 2:23
  • \$\begingroup\$ I'm neither golfer nor a programmer, basically came here by accident, but wow, this is just... so wrong... \$\endgroup\$
    – tomasz
    Commented Sep 14 at 14:48
12
\$\begingroup\$
  1. Use *a instead of a[0] for accessing the first element of an array.

  2. Relational operators (!=, >, etc.) give 0 or 1. Use this with arithmetic operators to give different offsets depending on whether the condition is true or false: a[1+2*(i<3)] would access a[1] if i >= 3 and a[3] otherwise.

\$\endgroup\$
1
  • 13
    \$\begingroup\$ a[i<3?3:1] is two characters shorter than a[1+2*(i<3)]. \$\endgroup\$ Commented Jun 13, 2015 at 4:15
12
\$\begingroup\$

Assign instead of return.

This is not really standard C, but works with every compiler and CPU that I know of:

int sqr(int a){return a*a;}

has the same effect as:

int sqr(int a){a*=a;}

Because the first argument is stored into the same CPU register as the return value.

Note: As noted in one comment, this is undefined behaviour and not guaranteed to work for every operation. And any compiler optimization will just skip over it.

X-Macros

Another useful feature: X-Macros can help you when you have a list of variables and you need to do some operation which involve all of them:

https://en.wikipedia.org/wiki/X_Macro

\$\endgroup\$
5
  • 4
    \$\begingroup\$ I quoted this and I was corrected, This is simply not true. It will only work with multiplications and divisions and when optimizations are turned off. This is because both operations happen to put their results in eax which is the common register for return. Parameters are stored either in the stack or ecx or edx. Try it yourself. \$\endgroup\$
    – Gaspa79
    Commented Apr 9, 2017 at 20:15
  • 4
    \$\begingroup\$ You are right, it's undefined behaviour, it also depends on the compiler and on the architecture, I usually check with gcc on x86 and armv7 before posting any answer using this trick. And of course if you enable optimization, any smart compiler would just delete the unnecessary multiplication. \$\endgroup\$
    – G B
    Commented Apr 10, 2017 at 6:25
  • 3
    \$\begingroup\$ I've seen this work with GCC but not others \$\endgroup\$ Commented May 21, 2017 at 7:10
  • 4
    \$\begingroup\$ @Gaspa79: gcc with -O0 always chooses to evaluate expressions in the return-value register. I've looked at x86, ARM, and MIPS at least (on gcc.godbolt.org), and gcc seems to go out of its way to do that at -O0. But remember if you take advantage of this, the language you're programming in is gcc -O0, not C, and you should label your answer accordingly, not as C. It fails at any optimization level other than -O0 debug mode, and doesn't work with clang IIRC. \$\endgroup\$ Commented Jun 14, 2018 at 15:18
  • 2
    \$\begingroup\$ I answered an SO Q&A about exactly why this works with gcc -O0, under what conditions: Return value in unused parameter when falling off the end of a non-void function (I didn't get into the GCC source code to look for that level of detail, but covered why assignment always "works": stores need the source value in a register, so GCC can't ever avoid evaluating into some register. And it always picks the return-value register.) \$\endgroup\$ Commented Sep 20, 2021 at 14:13
11
\$\begingroup\$

You may look into the IOCCC archives (international obfuscated C code contest).

One notable trick is to #define macros whose expansion has unbalanced braces/parentheses, like

#define P printf(
\$\endgroup\$
3
  • 18
    \$\begingroup\$ The mismatched parentheses have no value in themselves. The point is to define as much of the repeating pattern as possible. You might want to go further, with #define P;printf(. \$\endgroup\$
    – ugoren
    Commented May 8, 2012 at 7:25
  • \$\begingroup\$ How does this shorten byte count? Perhaps provide an example? \$\endgroup\$
    – Cyoce
    Commented Sep 19, 2016 at 5:07
  • 3
    \$\begingroup\$ @Cyoce See for example this answer. \$\endgroup\$ Commented Apr 30, 2018 at 12:56
11
\$\begingroup\$

dprintf for conditional printing

As you may know, printing something by a condition can be done with ?:, && or ||:

cond&&printf("%d\n",n);
cond||printf("%d\n",n);
cond?:printf("%d\n",n);

Another interesting idea is to use dprintf, which is the same as printf except that it takes an extra argument, specifying the output file descriptor. It will only output to STDOUT if said argument is equal to 1. This can be abused to potentially save a few bytes over the previously mentioned methods:

x-1||printf("%d\n",n);
dprintf(x,"%d\n",n);
\$\endgroup\$
10
\$\begingroup\$

Swap variables

If you ever need to swap variables, don't use the pattern with an extra variable or that addition-subtraction-method, just do some chained XORing:

a^=b^=a^=b;
\$\endgroup\$
2
  • 5
    \$\begingroup\$ This is undefined behavior, due to a lack of sequence points in between two modifications of the same object. See here: stackoverflow.com/questions/9958514/… \$\endgroup\$
    – 2501
    Commented Apr 23, 2017 at 19:44
  • \$\begingroup\$ This is incredible. 10+ years of coding C and I've always wondered if there was a way to do this, what a delight to stumble upon tonight \$\endgroup\$ Commented Feb 12, 2021 at 7:50
9
\$\begingroup\$

Using asprintf() saves you the explicit allocating and also measuring the length of a string aka char*! This isn't maybe too useful for code golfing, but eases the everyday work with a char arrays. There are some more good advises in 21st Century C.

Usage example:

#define _GNU_SOURCE
#include <stdio.h>

int main(int argc, char** argv) {
  char* foo;
  asprintf(&foo, "%s", argv[1]);
  printf("%s",foo);
}
\$\endgroup\$
9
\$\begingroup\$

for(int i=0;i<n;i++){a(i);b(i);} can be made shorter a few ways:

for(int i=0;i<n;){a(i);b(i++);} -1 for moving the ++ to the last i in the loop

for(int i=0;i<n;b(i++))a(i); -3 more for moving all but one statement into the top and out of the main loop, removing the braces

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Using the comma operator is another way to avoid braces in some cases. \$\endgroup\$ Commented Jun 14, 2018 at 15:22
9
\$\begingroup\$

Go functional!

If you can reduce your problem to simple functions with the same signature and defined as single expressions, then you can do better than #define r return and factor-out almost all of the boilerplate for defining a function.

#define D(f,...)f(x){return __VA_ARGS__;}
D(f,x+2)
D(g,4*x-4)
D(main,g(4))

Program result is its status value returned to the OS or controlling shell or IDE.

Using __VA_ARGS__ allows you to use the comma operator to introduce sequence points in these function-expressions. If this is not needed, the macro can be shorter.

#define D(f,b)f(x){return b;}
\$\endgroup\$
1
  • 2
    \$\begingroup\$ As an alternative to __VA_ARGS__, there's the following GNU extension: D(f,b...)f(x){return b;} \$\endgroup\$
    – Maya
    Commented Jun 25, 2021 at 18:39
8
\$\begingroup\$
  1. use scanf("%*d "); to read the dummy input. (in case that input is meaningless in further program) it is shorter than scanf("%d",&t); where you also need to declare the variable t.

  2. storing characters in int array is much better than character array. example.

    s[],t;main(c){for(scanf("%*d ");~(c=getchar());s[t++]=c)putchar(s[t]);}

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Actually, I use %*d not only in Golf because it's also useful in situations where one would, for example, want to skip a newline in scanf("%[^\n]%*c",str); :) \$\endgroup\$
    – tomsmeding
    Commented Dec 22, 2013 at 21:21
8
\$\begingroup\$

Print a character then carriage return, instead of:

printf("%c\n",c);

or

putchar(c);putchar('\n'); // or its ascii value, whatever!

simply, declare c as an int and:

puts(&c);
\$\endgroup\$
4
  • 10
    \$\begingroup\$ It is probably worth pointing out that this depends on a little-endian architecture. If c is a big-endian int, then you'll just get the carriage return. (On the other hand, if c is a char, you might get random garbage after instead of a carriage return.) \$\endgroup\$
    – breadbox
    Commented Dec 17, 2013 at 2:51
  • \$\begingroup\$ @breadbox yep, you are totally right; I just edited: the last excerpt should use c as an int (which is frequently easy to declare as such). \$\endgroup\$
    – moala
    Commented Dec 17, 2013 at 14:05
  • \$\begingroup\$ Does puts(&c) really work? That wouldn't necessarily be null-terminated. \$\endgroup\$ Commented Jan 16, 2018 at 5:40
  • 4
    \$\begingroup\$ @EsolangingFruit On little-endian with 32-bit ints, an int 0 ≤ c < 256 is stored as the byte sequence c 0 0 0. When interpreter the address of c as char *, we see a singleton string: the character c, followed by a null byte. \$\endgroup\$
    – Dennis
    Commented Jan 28, 2018 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.