четверг, 29 января 2009 г.

Множество Мандельброта

На днях написал небольшую программу на Си, которая строит множество Мандельброта и сохраняет его в BMP-файл. Картинка получается большая (4096х4096), но имеет всего 16 цветов и поэтому весит порядка 8 МБ. А вот и сам код:
#include<stdio.h>/* this code draw Mandelbrot set and save it into BMP file */
unsigned long h[]={7753026UL,128L,7733248UL,2621440UL,268435456UL,268435456UL,
65536L,4L,0L,0L,0L,1048576L,0L,0L,65280L,336920320UL,673775380UL,1010630440UL,
1347485500UL,1684340560UL,2021195620UL,2358050680UL,2694905740UL,3031760800UL,
3368615860UL,3705470920UL,4042325980UL,4210753520UL,4294967290UL,4294967295UL}
;int main(int n,char**f){FILE*o=fopen("fractal.bmp","wb");if(NULL==o)return 1;
;fwrite(h,1L,118L,o);**f=0;int c,x,y;for(y=-2048;y<2048;++y)for(n=0,x=-3000;x<
1096;n=00,++x){float i,j,k;i=j=k=0;while(i*i+j*j<4&&n++<16){i=i*i-j*j+x/1600.0
;j=2*k*j+y/1600.0;k=i;}c=**f?fputc((c<<4)|(n&15),o):n&15;**f=!**f;}fclose(o);}

А вот такая получается картинка (уменьшенная копия):

четверг, 22 января 2009 г.

Hello, World!

Читая стандарт C99 я открыл для себя много нового и интересного. В частности мне понравились удивительные синтаксические конструкции которые можно создавать используя информацию из стандарта C99.

Приведу пример двух программ которые печатают "Hello, World!" на экран:
%:include<stdio.h>
main()<%char*a<::>=<%"Hello,World!",0%>;puts(a<:(int)a<:1:>:>);%>

#include<stdio.h>
int main()
{
puts((char<::>)<%<:0x8:>=0x6F,<:0xA:>=0x6C,<:0x9:>=0x72,<:0x0:>=0x48,
<:0x6:>=0x20,<:0x2:>=0x6C,0x6C,<:0x4:>=0x6F,<:0x1:>=0x65,<:0x5:>=0x2C,
<:0xB:>=0x64,<:0x7:>=0x57,<:0xC:>=0x21,0x00%>);
}

В обоих примерах используются так называемые диграфы, это пара символов призванная заменить один, их использование вполне допустимо в языке Си и тесно связано с его происхождением. Когда язык Си появился на свет, имелись клавиатуры на которых отсутствовали символы '{', '}', '[', ']', '#' и бог его знает какие еще. Но, как известно, эти символы широко используются в языке Си и, чтобы не ущемлять права владельцев подобных "клав" в стандарт были введены диграфы, которые позволяли заменить эти символы на пару других, например '{' и '}' заменяются на '<%' и '%>', а '[' и ']' заменяются на '<:' и ':>', а также '#' заменяется на '%:'. Кончено, в наше время это кажется странным, но из стандарта диграфы так и не ушли.

И если с первым примером все становится более-менее ясно, то вот второй, даже после "исправления" диграфов, кажется странным. Тут все дело в стандарте C99. Дело в том, что там позволяется делать интересные вещи: объявлять безымянные массивы и посылать их в функцию, а также явно задавать положение элементов в объявленном массиве. Т.е. конструкция (char[]){1, 2, 3, 4, 5} есть не что иное как массив, тот же самый результат даст конструкция (char[]){[1]=2, [0]=1, [2]=3, 4, 5}. Вот теперь все должно встать на свои места :)

Удачного кодинга!