1 2 3 4
7 8
Joined: 11/26/2005
Posts: 285
Warp wrote:
Can I ask you why you want to learn C, rather than, for example, C++, C# or Java?
I'm really a newb, so this may be wrong, but I've heard that: C++ is harder to learn for beginners (I've only known BASIC before) C# is basically limited to Microsoft hardware unless you use Mono Java is harmful to beginners Or, to put it simply, why not?
Warp wrote:
As for your question, can you be a bit more specific about what is it that you don't understand about arrays? Also, are you talking about static arrays or dynamically allocated ones? (Do you know the difference?)
I don't understand how they are implemented, the definition of 'array', and what they possibly could be used for.
Derakon wrote:
Knowing C is a bit like knowing assembly, in that it gives you a lot of insight into how computers "actually work" than higher-level languages do.
This is part of the reason I wanted to program in the first place. I'd rather learn how a computer handles logic, rather than making a game or something along those lines.
amaurea wrote:
An array is a continuous section of memory containing data of the same type...
Thank you for the explanation. I didn't get much of it, though. I'll read up on pointers and re-read your post. :)
Joined: 7/2/2007
Posts: 3960
In short, arrays are sequences of variables, each of which has the same type. For example, you can have an array of 10 ints, or an array of 50 chars. You can use the [] notation to extract an element from the array: foo[0] means the first item in the array named "foo", foo[1] is the second item, et cetera. This is called indexing into the array: the number is the index of the item. C does not prevent you from trying to use an invalid index; with an array of 10 ints, foo[9] is valid but foo[10] is not. If you try to do that, you will get garbage results because C just looks at whatever would be there if the array was that long, and return it. If you try to write to foo[10], then you might be modifying memory that's being used by something else, which will at best simply cause the program to crash (and at worst can cause just about any kind of bad thing you care to think of).
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
SXL
Joined: 2/7/2005
Posts: 571
dude, an array is just an indexed list. you can store stuff (of the same type) in there, and write/read each by its index. let's say, you got 10 numbers, first is mylist[0], second mylist[1]... last is mylist[9]. this way, you can process your stuff with loops :
int main() {
    int mylist[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int i;
    for(i = 0; i < 10; i++) {
        printf("%d ",i);
    }
}
this will display "0 1 2 3 4 5 6 7 8 9". hope this helps.
I never sleep, 'cause sleep is the cousin of death - NAS
Joined: 11/26/2005
Posts: 285
Yes, I understand it now. Thanks. :)
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
Swedishmartin wrote:
I'm really a newb, so this may be wrong, but I've heard that: C++ is harder to learn for beginners (I've only known BASIC before)
Then you have heard BS. For example, try to do this in C:
#include <string>
#include <iostream>

int main()
{
    std::string name;
    std::cout << "Enter your name: ";
    std::getline(std::cin, name);
    std::cout << "Hello, " << name << "!" << std::endl;
}
And when I say "try to do this", I mean exactly. Note that the above code doesn't limit the length of the entered string (except for available RAM, of course). So no artificial maximum lengths. I'll wait.
Active player (333)
Joined: 11/25/2004
Posts: 75
Warp wrote:
For example, try to do this in C:
Not sure what the problem is...
#include <stdio.h>

int main(){
    char* name = NULL;
    size_t len;
    printf("Enter your name: ");
    getline(&name, &len, stdin);
    printf("Hello, %s!\n", name);
    return 0;
}
Anyway, arrays are not as complicated as they may seem at first. I remember learning C from an old photocopied TurboC++ manual and getting to the part about arrays and being like "wtf is this? brackets and pointers?" But it's really not that bad. Googling "c array" turns up some good tutorials on arrays and pointers.
Currently working on: SNES Star Fox, Level 3 (100%, published) SNES Star Fox, Level 2 (33%, after Sector X) SNES Star Fox 2, Expert mode (100%, published)
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
YtterbiJum wrote:
getline(&name, &len, stdin);
That's not standard C. (Besides, you have a memory leak.)
Experienced player (702)
Joined: 2/19/2006
Posts: 742
Location: Quincy, MA
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int sum, x=1, y=1, z; srand(time(NULL)); x= 1+rand()%10; y= 1+rand()%10; sum = x + y; printf("Add these two numbers together: %d and %d, x, y); scanf(%d, &z); if( z=sum) answer= 1+rand()%3; if (answer=1) printf("Correct!"); else if (answer = 2) printf ("congrats!"); else printf("That's the right answer!"); if (z!=sum) printf("Sorry, that's incorrect."); return 0; Is the correct at all?
Super Mario Bros. console speedrunner - Andrew Gardikis
Editor, Active player (297)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
andrewg wrote:
Is the correct at all?
No. Your code is not properly indented. More seriously, I get the gist that it does not compile. Try tokenizing it and you should see what's wrong. Especially around the scanf() statement. There's another bug that doesn't prevent compilation, but will cause malfunction. Recall which operators are easily mistaken.
Banned User
Joined: 12/23/2004
Posts: 1850
spoiler: fcrpvsvpnyyl, gur svefg cevags fgngrzrag vf zvffvat gur raqvat dhbgr. gur "vs nafjre rdhnyf" yvarf fubhyq unir gjb rdhny fvtaf, abg bar; bgurejvfr lbh ner whfg nffvtavat n inyhr vafgrnq bs purpxvat vg. lbh ner nyfb zvffvat gur raqvat pheyl oenpr.
Perma-banned
Former player
Joined: 12/5/2007
Posts: 716
I took the liberty to patch it a little. Compacted the variables a tad and fixed your string in the first fprintf. Also, when checking something (like if 5 is equal to 2+3), you should use == as = always sets stuff but doesn't check if something's correct or not. Watch out which variables you use, some of them were never declared before. Actually, here it is in C++, not C.
#include <iostream>
#include <time>

int main()
{
	// random seeding and variable declaration
	srand(time(NULL));
	int x = 1+rand()%10;
	int y = 1+rand()%10;

	// asking for user input
	printf("Add these two numbers together: %d and %d\n", x, y);
	int z;
	std::cin >> z;
	int answer = 1+(rand()%3);

	// checking the user input
	if (z == x+y)
		if (answer == 1)
			printf("Correct!\n");
		else
			if (answer == 2)
				printf("Congrats!\n");
			else
				printf("That's the right answer!\n");
 	else /*if (z != x+y)*/ // commented out because it is always either true or false, no need to check it again
		printf("Sorry, that's incorrect.\n");

	return 0;
}
Feel free to ask for explanations if needed.
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
How about this version in C, from a programmer's point of view?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    const char* const msgs[] =
    { "Correct!", "Congrats!", "That's the right answer!" };
    const int msgsAmount = sizeof(msgs)/sizeof(msgs[0]);

    srand(time(0));
    int n1 = 1 + rand() % 10, n2 = 1 + rand() % 10, answer;

    printf("Add these two numbers together: %d and %d\n", n1, n2);
    scanf("%d", &answer);

    if(answer == n1+n2) printf("%s\n", msgs[rand() % msgsAmount]);
    else printf("Sorry, that's incorrect.\n");

    return 0;
}
(Not that this code is perfect from design point of view, but you should usually try to minimize the amount of conditionals and instead try to make things more generic. In this case an array makes it a lot easier to eg. add new possible congrat messages, or delete existing ones, by simply adding/removing them from the array, without having to write more conditionals for each one.)
Experienced player (702)
Joined: 2/19/2006
Posts: 742
Location: Quincy, MA
ugh, I'm terrible at this. :(
Super Mario Bros. console speedrunner - Andrew Gardikis
Joined: 2/14/2009
Posts: 1
Location: Norway
#include <stdio>
#include <stdlib>
#include <conio>
#include <time>

#define maxNumber 100
#define maxGuess 10

void seedNum(int n1, int n2);

int main() 
{
	int n1, n2, answer;
	seedNum(n1, n2);
	
	int numGuess = 0;
	while (numGuess != maxGuess)
	{
		printf("Add these two numbers together: %d and %d\n", n1, n2); 
		scanf("%d", &answer); 

		if (answer == (n1 + n2))
		{
			printf("Correct! Now follows a new one...\n");
			seedNum(n1, n2);
			numGuess = 0;
		}
		else
		{
			printf("Sorry, that's incorrect.\n");
			numGuess++;
		}
	}
	printf("Game Over.\n");

	// send any awaiting chars in input buffer and wait for a key press...
	fflush(stdout);
	getch();

	return 0; 
}

void seedNum(int n1, int n2)
{
	srand(time(0)); 
	n1 = 1 + rand() % maxNumber;
	n2 = 1 + rand() % maxNumber;
}

Or something like that, I haven't tested it. Somehow .h is automatically removed from the includes.
Player (121)
Joined: 2/11/2007
Posts: 1522
andrewg wrote:
ugh, I'm terrible at this. :(
Have faith, with experience you can beat these nerds. OTOH you can beat SMB unassisted way better than them. I believe in u.
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Joined: 11/26/2005
Posts: 285
I have a question! My question is regarding the C libraries. I've been reading about the details of how they work and so on. I've been reading a bit on Wikipedia about them, but their reason of existence eludes me.
C Standard Library wrote:
The C standard library consists of a set of sections of the ISO C standard which describe a collection of header files and library routines used to implement common operations, such as input/output and string handling, in the C programming language.
Okay, so the routines in libc (if I may call it that) are defined in a compiled library file, as opposed to completely in header files. That is, the libc functions aren't compiled into the program, but the program is linked to them instead.
C (programming language) wrote:
The C programming language uses libraries as its primary method of extension. In C, a library is a set of functions contained within a single "archive" file. Each library typically has a header file, which contains the prototypes of the functions contained within the library that may be used by a program, and declarations of special data types and macro symbols used with these functions.
The "archive" file referred to is a library, I assume. The header files contains code to access the functions in the library.
C (programming language) wrote:
Since many programs have been written in C, there are a wide variety of other libraries available. Libraries are often written in C because C compilers generate efficient object code; programmers then create interfaces to the library so that the routines can be used from higher-level languages like Java, Perl, and Python.
Lots of libraries are used, not just libc. But why would you use libraries? Why not just compile the functions into the program? Also, how are libraries compiled? Is library source code available (for example for the GNU Standard Library)? Would it be possible to make a "stand alone" program in C, that used no external libraries? If so, how? Someone please answer my questions! Thanks in advance.
Joined: 7/2/2007
Posts: 3960
Sometimes you do compile the functions directly into the program. When you do, you're statically linking the files; the opposite is dynamically linking. There's good reasons to do both. Statically linking helps keep your program independent of other files, but also means that your program will be much larger. Imagine if you had 300 programs that all statically linked a certain library. Every one of those programs is larger by the size of that library; that's a lot of wasted space! Of course, these days storage space is pretty cheap -- but there's still a cost. If you had five of those programs running at the same time, then you'd have five copies of the library loaded into RAM. Really you only need one, which the five programs can share. Dynamic linking (where the library is not compiled into the program, but is loaded at runtime) helps keep program sizes down, and in certain situations allows you to "upgrade" a program without having to recompile it (for example, if a security vulnerability is found in a networking library, you could replace the library without changing the program). Usually, though, changing the library means recompiling the program anyway because of changes in the way you interact with the library. Basically, dynamic linking is more complicated than static linking, but lets you do some things that you couldn't do with static linking.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Joined: 11/26/2005
Posts: 285
Thank you for clearing that up. :)
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
Consider this: Basically 100% of programs in any desktop OS (very especially the Unix-based ones, eg. Linux, but also mostly true for Windows) use the libc library (as well as a bunch of others). And this means everything: Not only programs you run, but basically everything the kernel runs, such as device drivers, windowing systems, window managers, all the tiny apps your window manager runs... The amount of different programs running in your computer can be really large. And basically 100% of them use libc, and a bunch of other system libraries. Even programs which have been written in a language completely unrelated to C will most probably require libc when run. libc is not a small library (and neither are the majority of the others). Imagine if every single such program had linked it statically to itself. This would mean that the entire libc library would be duplicated in RAM as many times as there are programs running. That could be well into the hundreds of times. Instead, libc and the others are dynamically loaded. The advantage of this is that all the programs using libc can share the one and same libc instance in RAM, so it only has to be loaded there once. All programs will then call that one instance. Then there are also the so-called static libraries. These libraries are linked to your program at compile time. The advantage of this is that your program becomes faster to compile (because you don't have to compile the library each time), and disk space is saved (because the object files of the library are not copied in your disk for each program source code which uses that library).
Joined: 11/26/2005
Posts: 285
Thank you too, Warp.
Warp wrote:
Then there are also the so-called static libraries. ... disk space is saved (because the object files of the library are not copied in your disk for each program source code which uses that library).
But wouldn't using many static libraries be more space-consuming than using one dynamic? Oh, and by the way: What if I wanted to make an executable without any library (including libc) dependencies? Would that be simple? Would it even be possible?
Banned User
Joined: 3/10/2004
Posts: 7698
Location: Finland
Swedishmartin wrote:
But wouldn't using many static libraries be more space-consuming than using one dynamic?
Yes, but sometimes you don't want to use a dynamic library eg. because the library is not very widely used (ie. can't be expected to be installed in all linux distros by default, for example) and you want to distribute a binary executable of your program. A static library will be linked to the executable at linking time. The advantage of having it as a (system-wide) static library is that if more than one program uses it, it will only be stored in your hard disk once, rather than once for each such program.
What if I wanted to make an executable without any library (including libc) dependencies? Would that be simple? Would it even be possible?
It is perfectly possible to create an executable which does not depend on any dynamic library whatsoever (and sometimes this is necessary when you are making eg. some very specialized ramdisk apps for a boot disk). I think gcc even has a command-line option for this precise purpose (-static). Of course your executable will probably become rather large.
Joined: 11/26/2005
Posts: 285
Thank you! I now know more. :)
Joined: 11/26/2005
Posts: 285
Hey, I tried to make a program that prints this:
Hello, World! 
ello, World! H
llo, World! He
for 30 lines, and I came up with this:
#include <stdio.h>
#define LTH 13

int main()
{
	int arr[LTH] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', ' '};
	int n, p;
	
	for(n = 0; n < 30; n++)
	{
		for(p = 0; p < LTH ; p++)
		{
			printf("%c", arr[p + n]);
			if(p + n == LTH)
			 p = -n;
		}
	printf("\n");
	}
	
	return 0;
}
The printed text is something like
ello, World!
             ello, World!
                          ello, World!
printing non-stop. What did I do wrong?
Editor, Active player (297)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Swedishmartin wrote:
		for(p = 0; p < LTH ; p++)
		{
			printf("%c", arr[p + n]);
			if(p + n == LTH)
			 p = -n;
		}
Consider what happens to the loop terminating condition "p < LTH" when you execute "p = -n;". When do you suppose the loop ends? The simplest solution for making this _work_ involves the modulo operator, but I'm providing thought fodder here, not the solution handed on a silver platter…
Editor, Active player (297)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
Bisqwit wrote:
not the solution handed on a silver platter…
But I can go with the old-fashioned [spоiler] tag. #include <stdio.h> int main(void) {   int a=0;   static const char str[] = "Hello, world! ";   const int len = sizeof(str)-1;   while(printf("%.*s%.*s\n", len-a%len, str+a%len, a%len, str) > 0)     a=(a+1)%len;   return 0; } Or alternatively: #include <stdio.h> int main(void) {   int a=0;   #define Message "Hello, world! "   static const char str[] = Message Message; /* Message appended twice */   const int len = sizeof(str)/2; /* Note: division by two also takes care of dropping the nul character that only appears once */   #undef Message   while(printf("%.*s\n", len, str + a) == len+1)     a=(a+1)%len;   return 0; }
1 2 3 4
7 8