1 2 3 4 5 6 7 8
Joined: 11/26/2005
Posts: 285
GMan wrote:
While those are good tips, I just meant be careful as you go on that clean, elegant, readable code are much more important that trying to do strange one liners. I'm not accusing you of doing any of those above, just a free floating tip.
Speaking of one liners:
int main() {char s[] = "int main() {char s[] = %c%s%c; printf(s, 34, s, 34); return 0;}"; printf(s, 34, s, 34); return 0;}
I feel pretty cool. (Thanks for the tip!)
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
Swedishmartin wrote:
int main() {char s[] = "int main() {char s[] = %c%s%c; printf(s, 34, s, 34); return 0;}"; printf(s, 34, s, 34); return 0;}
There are (similar) ways to do it without making the assumption that the quotation mark character has a value of 34 (in other words, it will then work even in systems which do not use ASCII). It can be a bit challenging to come up with the solution to that.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
Also I think you need to add in the include statement, as in
#include <stdio.h>
int main(){char s[]="#include <stdio.h>\nint main(){char s[]=%c%s%c;printf(s,34,s,34);return 0;}";printf(s,34,s,34);return 0;}
because printf is defined in stdio.h somewhat less convoluted yet also less awesome is a quine in Windows batch scripting or in Bash scripting, etc. BAT/CMD
@more %0
Bash
#!/bin/sh
more $0
Now I would like to know, what would likely happen when you try to compile and run this code?
int main(){for(int i=0,int *p=&i;p>0;*p=(int)p,p--);return 0;}
EDIT: I now know why the .h was getting removed from my posts.
i imgur com/QiCaaH8 png
Joined: 4/13/2009
Posts: 431
My guess is that when you run that code, you will get a spectacular crash!
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
arflech wrote:
Also I think you need to add in the include statement, as in
#include <stdio>
int main(){char s[]="#include <stdio>\nint main(){char s[]=%c%s%c;printf(s,34,s,34);return 0;}";printf(s,34,s,34);return 0;}
because printf is defined in stdio.h
If the function prototype, which for printf, is defined in stdio.h, is missing, in C, it is assumed, for the function prototype, that it is like int func(...), which for most systems, and for most functions, including printf, works appropriately. In short, omitting the #include is not wrong.
Now I would like to know, what would likely happen when you try to compile and run this code?
int main(){for(int i=0,int *p=&i;p>0;*p=(int)p,p--);return 0;}
I think the most likely thing to happen is a Segmentation fault, followed by the application terminating. Unless you run it on systems without memory protection, in which case you will get all the memory addressable by the program, starting from its stack, downto almost zero, overwritten by something else.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
I was about to try something cooler with the rand() function, but I didn't feel like putting in one of the many pseudo-random number generators available on the Internet and I wasn't aware it was in stdlib.h Also I am aware of various improper things still working, like one time when I included a header in a .c file, I used the C++ name for the header and it still compiled because I guess GCC allows you to do that.
nfq wrote:
Swedishmartin wrote:
Hello, I suck at computers :)
not really. compare to me, i hardly even know what "compile" means.
I know this was said more than a year ago, but I don't think it was answered in this thread: A program is compiled when it is transformed from human-readable source code into machine code, which is a set of numbers indicating instructions, memory locations, and values that is directly executed by a processor; more generally, a program can be said to be compiled by being translated into a "lower-level" language, which requires less abstraction to parse and execute, like when Java is compiled into Java bytecode, the .NET languages are compiled into CIL, Python is compiled into .pyc or optimized .pyo files, or one of many experimental languages is compiled into C (the further down-level you compile, the harder it is to write a compiler, and although C has its flaws, it's simple enough to translate another language into in a cross-platform manner). Some code is merely parsed and interpreted as it is, not compiled; Java bytecode is interpreted by the Java Runtime Environment, Javascript is interpreted by your browser's JavaScript engine (like Windows Script Host, JScript, Rhino, TraceMonkey, JavaScriptCore, KJS, or Futhark), batch files and bash scripts are interpreted by the command processor, and Lua and Lisp are interpreted by a variety of programs. It is possible to run some "compiled" languages as scripts, like C (as CScript), Scheme, and Python, and it is possible to compile some "interpreted" or "scripting" languages, as V8 (in Google Chrome) does with Javascript, because for many modern Web applications, the speed gain from running a compiled script outweighs the cost of compiling the script. I should mention that for most purposes, after a program is compiled, it needs to be linked to any external libraries before it can be run, such as the Windows system libraries, DirectX, OpenGL GLUT, or the external libraries for whatever GUI framework you use, like MFC, WTL, GTK, Qt, FLTK, wxWidgets, the last of which is recommended because it easily allows the creation of cross-platform code for GUI applications with a native look and feel and without a heavy runtime. This is done by a linker, and most IDEs and compiler toolchains will automatically do this immediately after compiling, because the bare object file is not useful by itself.
Bisqwit wrote:
Tub wrote:
s/works/depends on random factors/
Well, deterministic random factors. Those being the assumption that the two functions are placed adjacently in the code -- which they are when compiled with current versions of GCC or CL. (ICC untested) I'm not planning to use it for anything serious, though.
Your function-altering "gruu" code also works in the latest TCC: http://bellard.org/tcc/ I heartily recommend this compiler for making cute little programs like the ones in this thread; it doesn't compile C++ though...
i imgur com/QiCaaH8 png
Joined: 11/26/2005
Posts: 285
I just wanted to pop in and say: I still haven't learned pointers properly. For some reason they're significantly more difficult than anything else in C so far. I guess it's because I can't think of good uses for them outside of arrays, and passing reference rather than value to functions. But you can make pointers that point to functions, what does that accomplish? (Or rather, what would it be used for?) And it's possible to create a pointer that points to an array of pointers, and so on. Same question there. Also, the declaration annoys me. (EDIT: Said some half-truths here, removed) And can someone explain the null pointer to me? Why would you set it to a memory address that doesn't exist?
Joined: 7/2/2007
Posts: 3960
Being able to treat functions as data (a.k.a. function pointers) is very useful in certain situations. For example, let's say that you're making a drawing program, and you want to have a little dropdown menu that lets the user choose between drawing a rectangle, a circle, or a pentagon. Drawing is done by clicking on the canvas and then dragging out to a point, so your drawRectangle, drawCircle, and drawPentagon functions all take the same arguments: the center, and the position of the mouse.
void drawRectangle(Coord center, Coord mouse);
void drawCircle(Coord center, Coord mouse);
void drawPentagon(Coord center, Coord mouse);
Now, when the user tries to draw something, you could look at the current drawing mode and call the relevant function:
if (drawMode == RECTANGLE) {
    drawRectangle(center, mouse);
}
else if (drawMode == CIRCLE) {
    drawCircle(center, mouse);
}
else {
    drawPentagon(center, mouse);
}
Or when the user chooses their draw mode, you could just set a variable to hold the relevant draw function:
drawFunc = drawRectangle;
...
drawFunc(center, mouse);
Get the idea? As for the null pointer, NULL is a convenient "always invalid" value. There are situations where you want to know that something has not been initialized, or cannot be used; in those situations, you can simply set the value to NULL. You often can't use 0 or -1 or the empty string because those could be valid values; NULL is never valid.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Joined: 11/26/2005
Posts: 285
Derakon wrote:
Get the idea?
Yeah, thanks.
Derakon wrote:
You often can't use 0 or -1 or the empty string because those could be valid values; NULL is never valid.
But why set it to anything at all? You wouldn't normally set integer variables to null, so what's the reason for doing it here? Why not just set your pointers to &variable, instead of first setting them to null and then to &variable? Also, I took a look at the comp.lang.c FAQ:
Therefore, the preprocessor macro NULL is defined (by several headers, including <stdio.h> and <stddef.h>) as a null pointer constant, typically 0 or ((void *)0) (see also question 5.6).
I just got stuck on this:
((void *)0)
I understand that typecasting is going on, but what does that code really mean? Is it treating the constant zero as a pointer?
Joined: 4/7/2008
Posts: 117
Yes. 0 is an integer, while a pointer is not an integer; the types are incompatible. By casting to void*, it then becomes allowable (pointers are freely cast in C). This is not so in C++, where void* cannot be implicitly converted to other pointers, and 0 has special meaning. C++0x will introduce nullptr, which alleviates this issue.
Joined: 4/13/2009
Posts: 431
Swedishmartin wrote:
For some reason they're significantly more difficult than anything else in C so far. I guess it's because I can't think of good uses for them outside of arrays, and passing reference rather than value to functions. But you can make pointers that point to functions, what does that accomplish? (Or rather, what would it be used for?)
Have multiple locations point to the same value. This can make something shared, so each section has the same value and will not have to be updated if that value changes. Linked lists are a good example of this. Real-time insertions and deletions, aka linked lists. Replacing a pointer is not expensive at all when you consider having to move possibly megabytes of data when you insert or delete into an array. Two more good examples. But passing data by pointer is by far one of the most useful examples.
And it's possible to create a pointer that points to an array of pointers, and so on. Same question there.
Yes, yes and yes. A pointer can point to anything that has a valid memory location. A pointer has a memory address, an array has a memory address, and an array of pointers too, and so on. So a pointer to a pointer: T**.
Also, the declaration annoys me. (EDIT: Said some half-truths here, removed)
How so?
And can someone explain the null pointer to me? Why would you set it to a memory address that doesn't exist?
We are unable to say whether a pointer is valid or not. So once you are done with a pointer, you normally set it to NULL so that we can explicitly check for NULL and see if it is a valid pointer or not. Some functions may want a pointer to something but you might want to make this pointer optional. In that case, you can pass NULL in place of that pointer. The function can then check for NULL and see that it is not a valid pointer and ignore it. Otherwise we would get an access violation. Also, C++ does allow 0 as a null pointer and there is a reason for this. In C any pointer can be converted to void* and backwards. In C++, this is not allowed. Saying int* p = (void*)0; in C++ will give you a compile error. The workaround to this was simply making 0 into a magical number that can be implicitly converted into any pointer type. In C++0x (the upcoming standard for C++), they introduce the nullptr, which is the new null pointer constant. But the real reason behind this is buried deep in the C++ language. It is all about types, because the 0 constant does not play well with some templates. nullptr would fix this.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
The meanings of "void" are confusing... "void func(){}" indicates a function with no return value "int func(void){}" is a function explicitly indicated to have no arguments "void* f" is a generic pointer, which usually must be cast to a specific pointer type before it can be used, and the confusing thing of course is that there is no void type for variables. Another confusing thing is that "int *p" is a pointer to an int, while if you use "*p" anywhere else, that's actually the int that p points to; IMO the symbol to indicate a pointer should have been a different symbol, like &, because for "int i", "&i" is the address of i. C++ references aren't that confusing though; "int &p=i;" is a reference to "int i", and then "&p" is the address of that int (because whenever you use p, it's exactly the same as i and you do not explicitly dereference). References are also less confusing (and less powerful) because there is no analogue to pointer arithmetic, references cannot be made to refer to any other variables, and there are "no references to references, no arrays of references, and no pointers to references." (ISO standard for C++98) Oh, Derakon didn't mention that making functions that take "callback functions" as parameters is much less resource-intensive when you pass functions by reference, by making function pointers, because like all variables, if functions are not passed by reference, the whole function must be copied during the function call.
i imgur com/QiCaaH8 png
Joined: 4/13/2009
Posts: 431
It is true that references are less powerful than pointers, but they were never meant to replace pointers, only to exist alongside them to simplify certain things.
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
arflech wrote:
Now I would like to know, what would likely happen when you try to compile and run this code?
int main(){for(int i=0,int *p=&i;p>0;*p=(int)p,p--);return 0;}
Segmentation fault.
Bisqwit wrote:
If the function prototype, which for printf, is defined in stdio.h, is missing, in C, it is assumed, for the function prototype, that it is like int func(...), which for most systems, and for most functions, including printf, works appropriately. In short, omitting the #include is not wrong.
That may be so de facto with most C compilers (for historical reasons). However, AFAIK the C standard requires functions to be declared before they can be called.
Swedishmartin wrote:
I just wanted to pop in and say: I still haven't learned pointers properly. For some reason they're significantly more difficult than anything else in C so far.
With C++ it becomes even more complicated. You can have pointers to class member functions (and if the function is virtual, dynamic binding is performed appropriately when the function is called through that pointer), and even to class member variables (in other words, you have a pointer of type "an int member variable inside class X", which you can then make to point to a certain int variable inside any object of type X, and the pointer will work for any object you use). Fortunately those are seldom, if ever, needed in practice.
But you can make pointers that point to functions, what does that accomplish?
There's an example in the standard C library: qsort(). (C++ offers a much more practical and efficient solution to the same problem, though.)
arflech wrote:
Oh, Derakon didn't mention that making functions that take "callback functions" as parameters is much less resource-intensive when you pass functions by reference, by making function pointers, because like all variables, if functions are not passed by reference, the whole function must be copied during the function call.
Functions cannot be passed by value, nor can be copied. C is not that kind of language. I think you wanted to use some other term there instead.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
If Bisqwit was able to swap the locations in memory of two functions for his "gruu" code, why can't a function be copied? Also, I forgot to post earlier a strange thing I read about arrays in C: C89 actually requires the notation a[n] to mean the same thing as *(a+n), where pointer arithmetic is used, so "int a[2]={1,2};" followed by "printf("%i",1[a]);" would print "2" because 1[a]=*(1+a)=*(a+1)=a[1]=2. I'm not sure when that would ever be useful, except perhaps when writing and using some macro to make it that much harder for people to understand your code.
i imgur com/QiCaaH8 png
Joined: 4/13/2009
Posts: 431
Bisqwit did something that is not supported by the C standard. It is something that is OS-specific stuff. To be able to read and copy the actual code in memory is something the OS deals with. C does not care the slightest, so functions cannot be copied. Period.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
ohh ok As an aside, I just finished watching every single programming tutorial on http://xoax.net/ and those are probably the best-made tutorials on YouTube. It would be nice if the owner of the site also made a series on C (perhaps as a companion to the big one on C++ console applications), but he appears to be stretched thin with all of the series recently started already. The main issue I have is that he uses Visual Studio even for the general C++ tutorials, giving the impression that he is not writing cross-platform code, even though it looks as if he is. (For the Win32 and MFC series it is necessary to use Visual Studio though). Among the topics covered so far in his main series, Console C++, (not in this order) are preprocessor directives, data types, enums (but not structs or unions), branching (using if and switch), looping (while, do-while, and for, including how for is expressed using while), pointers and references (including function pointers and passing arguments by reference), namespaces, scope, arrays (including treating strings as char arrays and using pointer arithmetic), dynamic memory allocation, and object-oriented programming, which most of the newer videos are covering. That series just gave me the idea to make a video series on programming in C using TCC, a simple compiler for simple programs (now if only dietlibc could be ported to Windows or OS X...). I'm not sure I'm going to follow through with that idea though, because it takes a lot of work to make videos that are as clean and legible as XoaX.net's offerings. I sure won't do what most of the amateur "tutorial" makers do, running a screen-capture program, speaking into the microphone as I do it, and encoding at a horrendously low quality that makes it hard to read the code or understand what I say.
i imgur com/QiCaaH8 png
Banned User, Former player
Joined: 3/10/2004
Posts: 7698
Location: Finland
I have for long wondered the current trend of making all kinds of tutorials in video format, even tutorials which would be enormously more suitable in HTML form. Programming is a perfect example of something which would be much better taught in HTML form than in video. The reader can study the tutorial at his own pace, go back to check something he didn't understand, copy code from the web page to his text editor if needed, and so on. A HTML page also can link eg. to online reference manuals, have screenshots if necessary, and so on. What sense does it make to have a programming tutorial as a video?
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
showing what it looks like when you compile and then run programs Also this guy (Michael Hall) does have articles in HTML format to accompany the videos (which are usually less than 5 minutes each and not fast-paced), and they are not mere transcripts of the videos. The lessons involving more complicated programs refer to downloadable source code, while the articles for some other lessons do have copy-pastable source code, although again it is not always exactly the same as the code shown in the videos.
i imgur com/QiCaaH8 png
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Warp wrote:
What sense does it make to have a programming tutorial as a video?
Some things are just better taught by do-and-tell, at least when impressions are concerned: http://www.youtube.com/watch?v=Gzj723LkRJY
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
This is also another good example of a tutorial best done as a video: http://www.youtube.com/watch?v=twxEVeDceGw It's about using gdb to step through a program, starting with writing and compiling a simple C program using wide characters, so the viewer gets an idea of what the program is supposed to be doing. Also this video shows why SciTE is so awesome (the secret is Lua): http://www.youtube.com/watch?v=OWYdVmULKW0 He has some good Linux software development videos, including using Glade, the GNOME GUI designer. Also youhakim is good at making legible videos, like this one about making assembly code from C with GCC and then using OllyDbg on it in Windows: http://www.youtube.com/watch?v=Jt3aUqDxW_8
i imgur com/QiCaaH8 png
Joined: 11/28/2004
Posts: 138
One thing i learned while taking classes in C++ was that we would use a namespace statement, in most cases this would be
using namespace std;
In a lot of code I've seen here this statement haven't been used as much as I would do. Could anyone enlighten me of the usage of a namespace statement? Never really grasped the point of those, all I know is that they are more used in C#, but perhaps in a different way.
The best time you have is the time you share with other people.
Joined: 7/2/2007
Posts: 3960
Functions, variables, constants, etc. can be assigned to namespaces, which among other things lets you unambiguously refer to whatever variable you're using and enables you to have multiple things with the same name (but in different namespaces) without having a conflict. Without adding "using namespace std;" to your code, you'd have to write e.g. "std::cout" instead of just "cout". It took me a long time to realize how useful namespaces are. Their utility doesn't really show up in small programs, but they're a big help once you start getting more complicated programs with large numbers of source files.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
arflech
He/Him
Joined: 5/3/2008
Posts: 1120
It is not a good idea to put a using declaration in the global scope, like right after the include directives, because it is then too easy for namespaces to clash. Also the ANSI-C version of Bisqwit's code can at least be compiled into a much smaller executable with TCC; I got 3KB with TCC, while compiling the C++ programs with GCC (TCC does not support C++) and then compressing with UPX yielded half a megabyte.
i imgur com/QiCaaH8 png
marzojr
He/Him
Experienced player (749)
Joined: 9/29/2008
Posts: 964
Location: 🇫🇷 France
arflech wrote:
Also the ANSI-C version of Bisqwit's code can at least be compiled into a much smaller executable with TCC; I got 3KB with TCC, while compiling the C++ programs with GCC (TCC does not support C++) and then compressing with UPX yielded half a megabyte.
Did you remember to strip the executable when compiling with GCC (pass a -s option in the command line or run strip on the executable)? That is a common mistake which results in executables that are larger than needed, as GCC includes some debugging information by default.
Marzo Junior
1 2 3 4 5 6 7 8