Hey, Im not very sure on how to use functions in C. Basically Im making a roman numeral calculator. Iv writen the code for converting from roman numeral to decimal. How can I make this into a function and what would I need to do to use this function, given that that roman characters are stored in "inchararray1". Things that the function needs are the lenght of the string (length) and the char array "chararray". The only value its to return is "input" Pretty please help. for (i=0;i == length; i++) { switch chararray(i) { CASE M: decimal(i) = 1000; break; CASE D: decimal(i) = 500; break; CASE C: decimal(i) = 100; break; CASE L: decimal(i) = 50; break; CASE x: decimal(i) = 10; break; CASE V: decimal(i) = 5; break; CASE I: decimal(i) = 1; break; default: printf("non roman numeral conversion attempted"); break; } for (i=0;i == length; i++) { IF (decimal(i) == 1) && (decimal(i+1) == 5) || (decimal(i+1) == 10)) {decimal(i) = -(decimal(i));} IF ((decimal(i) == 10) && (decimal(i+1) == 50) || (decimal(i+1) == 100)) {decimal(i) = -(decimal(i));} IF ((decimal(i) == 100) && (decimal(i+1) == 1000)) {decimal(i) = -(decimal(i));} input = input + decimal(i);
ummm... man, I'm sure you'll get plenty of responses better than me since it's been 2 years since C.. let's see #include <stdio.h> WonderTwinPowersActivate(char [] chararray, int length) { //that might be char inchararray1[]... I can't remember for (i=0;i == length; i++) { switch chararray(i) { CASE M: decimal(i) = 1000; break; CASE D: decimal(i) = 500; break; CASE C: decimal(i) = 100; break; CASE L: decimal(i) = 50; break; CASE x: decimal(i) = 10; break; CASE V: decimal(i) = 5; break; CASE I: decimal(i) = 1; break; default: printf("non roman numeral conversion attempted"); break; } for (i=0;i == length; i++) { IF (decimal(i) == 1) && (decimal(i+1) == 5) || (decimal(i+1) == 10)) {decimal(i) = -(decimal(i));} IF ((decimal(i) == 10) && (decimal(i+1) == 50) || (decimal(i+1) == 100)) {decimal(i) = -(decimal(i));} IF ((decimal(i) == 100) && (decimal(i+1) == 1000)) {decimal(i) = -(decimal(i));} input = input + decimal(i); } main() { WonderTwinPowersActivate("iv", 2); } ********** on a side note, when you reference a point in an array like your line : switch chararray(i) those ()'s need to be []'s I'm pretty sure. Sorry if I'm wrong on some parts or maybe was thinking of java or C++, but I'm no programmer, I'm more into hardware... but I do have to program sometimes Oh, also you can do all that in the main function and use argv and argc[] to pass in the char array. I could tell you how, but then I'd have to kill you (and I"m too lazy to pull out my old C programs from 2 years ago )
yes, they have to be []... so your switch statement would be switch (chararray) Also, your function can be WonderTwinPowersActivate(char *chararray, int length) as well, as array's are just pointers (if you are just starting out, you'll learn these soon).
Check this out, very valuable to me when I was learning c++. Functions 1. http://www.cplusplus.com/doc/tutorial/tut2-2.html Functions 2. http://www.cplusplus.com/doc/tutorial/tut2-3.html Main index. http://www.cplusplus.com/doc/tutorial/index.html
Just a note, C and C++ are different in some ways. For instance, printing to screen is a big one So if you use those guides and are learning C (not C++) you won't be able to use everything. To be honest, I don't recall using malloc in C++, so I think that's another big difference. Of course, as always with programming things, I could be wrong (but I know for a fact there are many differences) edit: just looked up dynamic memory allocation in those tutorials, and it's just like I thought I remembered... new/delete for C++, malloc and.... I can't remember how to unallocate memory in C, but whatever. It might be delete as well /shrug Sorry I'm so scatter-brained with programming. I got too many languages from too long ago floating around in my head
The operator new and delete are C++ not C as you point out. You can of course use malloc/free (and the other associated memory allocation calls, realloc, etc.) in C++ but they do differ from new and delete. new and delete deal with memory allocation as do malloc/free but they also call the relevant class constructors/destructors. As both new and delete are operators in C++ they can be overloaded, which makes adding in custom memory managers significantly easier too. There seems to be quite a lot of 'bugs' in that first lot of code you posted. Keywords should be lowercase (case not CASE, if not IF, etc). As already pointed out array deferencing should be with brackets not parentheses. Your for loop looks dodgy too, you probably want the looping condition to be i < length. One thing that's not a bug, but should really be changed is the postincremenet 'i++' in the loop. That section of code is always executed at the end of each loop iteration so you can use ++i (preincrement) instead, which is faster (a temporary value doesn't need to be stored to be returned from the operator). It won't make much of a difference in your case but in large loops it will speed things up slightly.
thats becuase u dont you use new to allocate space for objects and delete to destroy objects in C++ In C, malloc is to allocate space, realloc is to allocate, adjust or free space (depending on the parameters) and free is to free space, all of which is referenced by a pointer. + C++ is very different to C becuase it uses encapsulation, polmorphism around objects, it is true that in C you can use structures to provide a similar structure but not to the same level....
Oh crikey memory allocation under the hood.... There are a number of functions here void *malloc( size_t size ); malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small. .....which can also resolve to malloc_dbg when _DEBUG is specified void *_malloc_dbg(size_t size, int blockType, const char *filename, int linenumber ); _malloc_dbg is a debug version of the malloc function. When _DEBUG is not defined, each call to _malloc_dbg is reduced to a call to malloc. Both malloc and _malloc_dbg allocate a block of memory in the base heap, but _malloc_dbg offers several debugging features: buffers on either side of the user portion of the block to test for leaks, a block type parameter to track specific allocation types, and filename/linenumber information to determine the origin of allocation requests. _malloc_dbg allocates the memory block with slightly more space than the requested size. The additional space is used by the debug heap manager to link the debug memory blocks together and to provide the application with debug header information and overwrite buffers. When the block is allocated, the user portion of the block is filled with the value 0xCD and each of the overwrite buffers are filled with 0xFD. void *calloc( size_t num, size_t size ); The calloc function allocates storage space for an array of num elements, each of length size bytes. Each element is initialized to 0. calloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when calloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. void *realloc( void *memblock, size_t size ); The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to malloc, or realloc. The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument. Note: realloc calls malloc void free(void *memblock ); The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors. New and, Delete operators The new and delete operators are C++ operators only. In reality though they call through to (iirc) malloc (for new) and (free) for delete. However, Hargle is exactly right - although they allocate the memory; they also call the constructor of the class before returning, or destructor before the memory free. One interesting point is that new cannot be used to allocate memory for a function, only a function pointer!
Well, I really don't think all this memory allocation talk went along with the original post since he won't really need to do it. I was just mentioning differences between C and C++ so he doesn't get the two confused and said that was one of the differences. I think it's really funny this turned into a malloc discussion
C++ or not, this code will work and will be faster and cheaper. Evil the Cat, it looks good for a beginner, but remember to keep it simple and you'll have an easier time of it. Code: #include <stdio.h> int fromromannumeral(char *); int fromromannumeral(char *chararray) { int input=0; for (i=0;chararray[i];i++) { chararray[i] |= 0x20; //Make it lower case switch (chararray[i]) { CASE 'm': input += 1000; break; CASE 'd': input += 500; break; CASE 'c': input += 100; break; CASE 'l': input += 50; break; CASE 'x': input += 10; break; CASE 'v': input += 5; break; CASE 'i': input += 1; break; default: printf("non roman numeral conversion attempted"); break; } } return input; } void main() { printf ("IV in decimal: %i", fromromannumeral("iv")); } Try it out.
Not tried this (I'm going to to though...) cos I dont think it will work! Your parsing the string left to right adding the numbers found - but Roman numerals dont work like that. "IV" is not the same as "VI" which is what I think your routine would do - the first is decimal 4 the other is decimal 6. Effectively none of the routines take into consideration the rule that if the numeral to the left of the next is worth less, its subtracted not added. I noticed this before but got competley sidetracked by the memory blag......
Wibble - Self explanatory I hope --- Was this still required. Not fully tested - but seems to work for XIV XVI etc... Code: // RomanNumeral.cpp : Defines the entry point for the console application. // #include "stdafx.h" int GetDecValue(char roman) { int nVal = 0; switch (roman |= 0x20) { case'm': nVal = 1000; break; case'd': nVal = 500; break; case'c': nVal = 100; break; case'l': nVal = 50; break; case'x': nVal = 10; break; case'v': nVal = 5; break; case'i': nVal = 1; break; default: printf("non roman numeral conversion attempted"); nVal = -1; break; } return nVal; } int DecodeNumeral(char* pNumerals) { int lastVal = 0; int thisVal = 0; int nTotal = 0; // loop through roman numeral array for (int i = 0; pNumerals[i]; i++) { // remember last when adding on lastVal = thisVal; thisVal = GetDecValue(pNumerals[i]); // if no error.... if (thisVal > 0) { // add decimalised value to total nTotal += thisVal; // if previous was less than current need to subtract twice its amount if (lastVal < thisVal) nTotal = nTotal - (2*lastVal); } else { // error in translation - bug out nTotal = -1; break; } } return nTotal; } int _tmain(int argc, char* argv[]) { if (argc == 2) { return = DecodeNumeral(argv[1]); } else { printf("\nUsage: RN.EXE {xx}"); printf("\nxx = Roman Numeral to be converted to decimal."); return -1; } }