Tag Info

New answers tagged

0

You would usually want your zero (in fact variable) size array to know its size at run time. Then pack that in a struct and use flexible array members, like e.g.: struct my_st { unsigned len; double flexarray[]; // of size len }; Obviously the flexible array member has to be the last in its struct and you need to have something before. Often that ...


1

String literals like "name" are stored as arrays of char (const char in C++) such that they are allocated when the program starts and held until the program terminates. The type of the expression "name" is "5-element array of char" (5th element for the 0 terminator). Except when it is the operand of the sizeof or unary * operators, or is a string literal ...


3

Let's look at how an array is typically laid out in memory: +----+ arr[0] : | | +----+ arr[1] : | | +----+ arr[2] : | | +----+ ... +----+ arr[n] : | | +----+ Note that there isn't a separate object named arr that stores the address of the first element; when an array appears in an ...


0

Don't use a circular array at all. It's way simpler and more efficient to just use a regular array where you fill gaps by swapping with the backmost value of the array, and only manipulate the end index when you add or remove elements. As said by others, a binary heap is the standard way to implement a priority queue, and you will benefit from this same ...


2

The problem with using an array (circular or not) as underlying data structure for a priority queue is that you must always copy elements around to create a hole where a new element should be inserted or to fill the hole created by removing an element. In a very naive implementation, using your circular array, you could use the following scheme: When ...


4

As a simple fix you can swap the max element with first and then pop as normal. However I suggest using a max-heap structure. This has the advantage of having only O(log n) time complexity for push and pop and can fit in your fixed size array. Popping a value involves putting the last element in the head and shifting it down. Pushing a value involves ...


4

This is just the way string literals work in C. String literals like "name" are arrays of characters, it is equivalent to the five element array {'n', 'a', 'm', 'e', '\0'}. For the code char *c; c="name"; the environment reserves memory for the above array already at initialization time, when the program is loaded from disk into memory. At run time, the ...


1

If you want a pointer to a memory address, declare one. An array actually points at a chunk of memory you have reserved. Arrays decay to pointers when passed to functions, but if the memory they are pointing at is on the heap, no problem. There is no reason to declare an array of size zero.


10

The issue I would wager is that C arrays are just pointers to the beginning of an allocated chunk of memory. Having a 0 size would mean that you have a pointer to... nothing? You can't have nothing, so there would have had to be some arbitrary thing chosen. You can't use null, because then your 0 length arrays would look like null pointers. And at that ...


-2

There are various level of embedded platforms using C as programming language ( of course it is your freedom to use assembly language at any time ) For 'Level' I am talking about the Internal SRAM and ROM resource level for a system. These platforms sometimes are resource constrained ( e.g. some 8051 platforms only have 128 bytes of User SRAM ). It is ...


3

First, it's undefined behaviour. Some optimising compilers nowadays get very aggressive about undefined behaviour. For example, since a-- in this case is undefined behaviour, the compiler could decide to save an instruction and a processor cycle and not decrement a. Which is officially correct and legal. Ignoring that, you might subtract 1, or 2, or 1980. ...


1

...simply decrementing a pointer outside of the allocated range seems highly sketchy to me. Is this "allowed" behavior in C? Allowed? Yes. Good idea? Not Usually. C is a shorthand for assembly language, and in assembly language there are no pointers, just memory addresses. C's pointers are memory addresses that have a side behavior of incrementing ...


10

Officially, it's undefined behavior to have a pointer point outside the array (except for one past the end), even if it's never dereferenced. In practice, if your processor has a flat memory model (as opposed to weird ones like x86-16), and if the compiler doesn't give you a runtime error or incorrect optimization if you create an invalid pointer, then the ...


12

You are right that code such as float a = malloc(size); a--; yields undefined behavior, per the ANSI C standard, section 3.3.6: Unless both the pointer operand and the result point to a member of the same array object, or one past the last member of the array object, the behavior is undefined For code like this, the quality of the C code in the ...


3

You can't make new functions "built-in" to C without changing the compiler. However, you can write and extend libraries with new functions that your programs can then reuse wherever they want. For that, you need to compile a library with the functions, your program needs to include the library header file, and the linker has to include the object code for ...


1

How could it be possible to use a single n box as my tutor taught? Won't a new n box be created whenever factorial(n - 1) is called? Yes, exactly. Each time you call a function, additional memory is set aside for the function arguments and local variables. Let's drop a couple of levels below C and talk about how a compiled program is laid out in ...


1

In your current design, the Logic module already has a dependency on the Logger module, but that dependency is hidden. The dependency lies in the fact that both Logic and Logger must agree on the set of functions used for logging (one function) and their signatures (void (char*)). The way out of here is to clearly separate the interface from the ...


0

Logic.h declares a function to set the logger function: Logic_SetLogger(), in order to use it. Therefore, Logic.h must know the prototype of the logger function, whatever Logger.h is, i.e., in the most generic way possible. This is already the case with the first argument: a pointer to a char. For the second argument, I see two alternatives: The usual ...


1

I don't think having a bunch of printlns is a design issue at all. The way I see it is that this can clearly be done with static code analyzer if it is really a problem. But it is not a problem because most people don't do IOs like this. When they really need to do lot of IOs, they use buffered ones (BufferedReader, BufferedWriter, etc..) when the input is ...


1

While the performance is not really an issue here, the bad readability of a bunch of println statements points to a missing design aspect. Why do we write a sequence of many println statements? If it were just one fixed text block, like a --help text in a console command, it would be much better to have it as a separate ressource and to read it in and write ...


-1

From a c# perspective K&R might be a great book on c ... i recently read it in an attempt to brush up on c. I have to say the code in it makes my eyes bleed (when having a c# hat on). In c# the current style is to make everything clear and not ram 4+ statements into one. If you want to learn c# this is not the place to start. I cannot recommend a book ...


4

Firstly, let me agree that K&R is a great place to start with the C family. It is a really wonderfully written book. Importantly, it is quite concise. Be aware that C++ is much more closely related to C that C#, although C# does borrow heavily from both. Java in fact does the same, and indeed C# followed from Java. You can't learn C# or C++ just using ...


1

In higher level languages like C and C++, this is less of a problem than in Java. First of all, C and C++ define compile-time string concatenation, so you can so something like: std::cout << "Good morning everyone. I am here today to present you with a very, " "very lengthy sentence in order to prove a point about how it looks strange " ...


24

There are two 'forces' here, in tension: Performance vs. Readability. Let's tackle the third problem first though, long lines: System.out.println("Good morning everyone. I am here today to present you with a very, very lengthy sentence in order to prove a point about how it looks strange amongst other code."); The best way to implement this and keep ...


37

I understand the book is written to describe C languages in general. The book is written to teach you ANSI C, not 'C languages in general' Does the book expect me to be able to translate the first program ... to a C# or C++ program? No, those are different languages, and the book does not expect you to do anything with those languages. The ...


0

The K&R book is a great place to start with any of the C variants. The short answer is that you can run C code through a C++ compiler and it will run. Some things you need to know: When C++ was introduced, it updated C's capabilities by (at a minimum) adding object oriented coding to C. (UPDATE) As many of you have noted, the languages are not the ...


1

Most of the time, people in companies will have an official title and then wear many hats. So the your mileage with any given title will vary, especially if a business's goals are changing, like if they're moving from a product to service oriented business. With that in mind, I'll describe how those titles usually start out. A programmer analyst typically ...


1

Generally speaking, this is a fine idea and many packages do this. You might look at RSQLite for inspiration -- they package up sqlite and just include some wrapper functions. Similar for rhdf5 and hdf5 Regarding your points: Write tests for existing functionality Always a good idea! Keep the C library inside the src/ folder Yes -- or you could ...


1

There is actually quite a lot of difference. The C code uses unformatted, unlocalized output. The C++ equivalent has quite a lot of gunk in it for changing locales and that kind of thing. Functionally, they are far from equivalent. You just happen to be using only a tiny subset of the C++ interface. However more generally, the larger code sizes are a defect ...


0

A pointer-to-pointer simply means that you have an address of a memory location where some other pointer is stored. You dereference it twice to get to the final typed value. int i = 123; int* pi = &i; int ** ppi = &pi; int j = **ppi; There are a surprising number of situations in which you need to use one of these beasties. As an output argument ...


1

Multiple indirection generally occurs in the following scenarios: writing to a parameter of pointer type, and building an N-dimensional array by pieces. Writing to a parameter of pointer type For any function parameter of type T, if you want the function to modify the value of the parameter and have that new value reflected in the caller, you must pass a ...


5

There doesn't seem to be much difference in the code above. Yes there is. It's a totally different code. The c++ iostream library relies heavily on template which creates more inline code and so the C++ executable is bigger. Another reason is that you did not remove debug sympols from the executable files, and for C++ the symbols are quite verbose. If ...


4

The difference in executable sizes will be heavily dependent on what type of linkage is specified, optimisations and the compiler(s) being used. Given the significant difference in final sizes, it looks like the C++ variant is being statically linked with the runtime. Remove or change that and you should see a drop in the C++ size; for gcc (g++) look for ...


12

Most of the C++ standard library, including all the streams which cout is part of, are inline template classes. Whenever you #include one of these inline library components, the compiler will copy and paste all that code to the source file that is including it. This will help the code to run faster, but will also add a lot of bytes to the final executable. ...


3

ptr_ptr is a pointer to a pointer to an int, and it points at ptr. ptr is a pointer to an int, and it points at n. n is an int, which has been set to 10. A prefix '*' is the de-reference operator, meaning "the thing pointed to by". So **ptr_ptr evaluates to *ptr which evaluates to n, which is 10. If it helps, consider **ptr_ptr as equivalent to ...


1

The = in C does not mean mathematical equality. For mathematical equality, in C you could write, for example: n == n + i This is a logical expression whose value will be true when the value of i is zero, and false at any other time. The expression n = n + i means, "Modify n so that the new value of n will equal the sum of i added to the old value of n." ...


0

As Bart van Ingen Schenau points out, C++ doesn't have garbage collection. That means for the most part you must restrict your designs to ones where every object has a single unambiguous owner that disposes of it when the owner goes out of scope. Anything more complicated runs the risk of a memory leak.


9

In terms of OO design, you don't have to change all that much when going from Java to C++. The majority of the design principles is actually language independent and applicable to both Java and C++. How you express your design in code can differ quite a bit between languages. The most important thing to remember is C++ does not have automatic garbage ...


0

No, you don't need to change anything in your design if your design was well thought out from the start. OOD should be language agnostic, that means you should be able to pick any OO language and implement it.


1

Yes, I as far as I can tell the expression in the form you have written it will produce a very good approximation to the correct result of evaluating that formula over a very large range of input values. You have performed a specific simplification of one constant calculation, for reasons I do not understand. If you're going to simplify one calculation, why ...


7

This is a very good question -- to ask your instructor. She no doubt has a plan (or syllabus) of what she's going to teach and the order she's going to teach it in. The first example you show with the for loop might come of of chapter 1 in a text book, while recursion and the factorial example might come from chapter 5. We don't know what's in chapters 2 ...


2

The answer is almost as embarrassingly simple. No, absolutely not, and anything you do to change what you have written will most likely be wrong until you have read and understood What Every Computer Scientist Should Know About Floating-Point Arithmetic I only understand about 1/4 of that paper, but I understand enough of it to know that my chances of ...


6

A PDP minicomputer with only 8 kB of memory can't allocate a very large stack. So, on such a machine, one has to be careful in a language design (or evolution) to be able to minimize what needs to go on the stack for expected common subroutine call usage. C is still used today to program extremely memory constrained (a few kB) embedded systems, so the ...


11

My first guess for the reason was simply because of performance and memory saving reasons, and for the ease of compiler implementation as well (especially for the kind of computers at the time when C was invented). Passing huge arrays "by value" seemed to have a huge impact at the stack, it needs a full array copy operation for each function call, and ...


3

It is likely some sort of optimization. Not all optimizations must be explicitly enabled. The safest ones will be enabled unless explicitly disabled, which seems to be the case here. Running the following command on my system shows 47 optimizations enabled by default: gcc -Q --help=optimizers


0

From The Development of the C Language: Structures, it seemed, should map in an intuitive way onto memory in the machine, but in a structure containing an array, there was no good place to stash the pointer containing the base of the array, nor any convenient way to arrange that it be initialized. For example, the directory entries of early Unix systems ...


5

As pointed out in this question, for the particular case of freeing memory immediately before terminating the program, free is a waste of time if your program runs on pretty much any modern operating system. You'll be making the allocator do the work of tracking down the memory and marking it as unused, despite the fact that the OS can free the memory in one ...


1

Each call to malloc allocates memory on the heap and returns a pointer to it. If you do not call free on the returned pointer, the memory is not freed (so you get a memory leak). In most trivial cases it is not really necessary to call free (i.e. the application will probably run fine without it), but most people (rightly) consider not freeing the memory a ...


1

If the object lives to the end of the program, then you don't need to call free, but I would hold that it is still good practice to do so. The reason here is that, at the end of your code's execution, all of the memory will be free'd anyway, so there's no need to do so explicitly. Otherwise, yes; use free always.


2

This is using O(1) (also Big-Theta(1), as the best-case and worst-case use are the same figure) space-complexity as the the amount of space needed to perform the operation does not increase with n.



Top 50 recent answers are included