This question already has answers here:
Array initialization C
(5 answers)
Closed 1 year ago.
I noticed a piece of code that made me raise a few eyebrows in the code base which I am working on.
Since I am not an expert of the C language, I first tried googling initializing fixed size arrays.
However, I could not find anything like that:
float array[7] = {0.0,};
To be precise, I would like to know how the comma is interpreted in C here? I doubt it is a typing error, because I find this kind of initialization all over the place and for all types of arrays.
Is there any difference to just writing:
float array[7] = {0.0};
This has nothing to do with floats. It goes for all arrays. Imagine that that rule did not exist and you you have this:
float arr[] = {
4.5,
2.3,
3.8
};
Later, you realize that you want to remove 3.8. Then you would ALSO need to remove the comma after 2.3. And the same thing goes if you want to insert a new value. Let's say that you have copied a value from somewhere. Now you cannot simply paste it. Because if the copied string has a comma, you could not simply paste it anywhere you want in the array.
The basic purpose is that you should not have to think about adding and removing commas. It's just convenience.
Imagine copying and pasting regular code and you would have to think about that for the semicolon everytime. That would be a bit annoying. That's how it is in Pascal. ;)
Related
This question already has answers here:
Creating an atoi function
(5 answers)
atoi implementation in C
(6 answers)
Closed 4 years ago.
I should first start out by saying that I come from a Java background. That being said, I'm just starting to learn C and I really struggle with the use of pointers. The concepts are simple enough, but actually using them proves to be a rather difficult and frustrating experience for me.
At any rate, I'm trying to create a function that replicates atoi without using the stdlib.h library. I'm thinking it's a simple matter of casting, but when I test it I get some really strange results. What I have is as follows:
int myatoi(const char* str){
return (int)*str;
}
Given that I don't really know what I'm doing when it comes to pointers, I'm most certainly doing something wrong, but I have absolutely no idea what.
That will not work. Casting will result in the "reinterpretation" of the first character (at location *str) into its ASCII value as an integer.
You will need to process the string by iterating through its characters and parsing them.
This question already has answers here:
How can a scalar be passed to a vector (1D array) to a Fortran subroutine?
(2 answers)
Closed 6 years ago.
Okay, so yesterday I had a co-worker coming into my office and asking me a question about Fortran code that he had to work with.
Basically, the code that he works with has a long, multidimensional array, and a subroutine that expects just this long, multidimensional array as a parameter.
However, the code calling that subroutine only passes the first element of the array. Yet the code works. So he asked me how that could be.
I haven't seen his particular code, but here's an example how I understand the issue (and it works!):
subroutine print_array(a)
implicit none
integer :: a(10)
write(*, *) a
end subroutine print_array
program passing
implicit none
integer :: i(10)
i = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
call print_array(i(1))
end program passing
So I told him that Fortran stores arrays sequentially, and the location of the array is the same as to the first element, and since the subroutine expects a certain shape, it knows how far to read along this sequence, and so on.
I also told him that this was bad programming practice and that he shouldn't write this kind of code himself.
But since then I have been wondering: Why did whoever wrote this do it this way in the first place? Is there any reason to do that? (It doesn't even have to be a good reason.)
Or am I right and this is just silly and far too error-prone?
Your explanation of how this works is correct. Your aversion to following this outdated practice is widely supported.
As for the reason, I've forgotten (though long ago I used to do it to -- like driving home from the pub and smoking, everyone did and thought nothing of it) but perhaps the earliest versions of the language didn't support passing the whole array as a parameter. Perhaps someone else, whose brain is not addled by the potent mix of booze, tobacco and FORTRAN (that's right, shout it out) remembers more clearly.
This question already has an answer here:
Creating variable names from parameters
(1 answer)
Closed 8 years ago.
Is is possible for your code to generate new variables in c? For example, if I made "example_variable = 15", is there any way to automatically generate 15 new variables such as: "generated_variable_1", "generated_variable_2", "generated_variable_3", all the way to "generated_variable_15"?
I'm very new to c, and I haven't had a proper introduction to it, so I only know the basics, especially when it comes to variables. I am pretty sure this is really high-level stuff, so I'm sorry if the question doesn't make sense. I am open to any suggestions for alternate ways of generating the variables.
I know there are probably answers already out there, but I've had trouble finding them and would like answers specific to what I'm looking for, as opposed to piecing together what I need from what I can find.
What you are talking about - generating variables at runtime - is not possible in C. The reason is that C is a low-level language and does not expose an API for runtime manipulation. In fact, once compiled, C programs don't use variables - are values are stored directly in memory using memory addresses.
The closet equivalent to what you're looking for that's available in C is an "array". To declare an array, you can do:
int var[15];
int var2[n]; // in C99+, n is a variable saying how many elements you want in the array
You can also do this with malloc, but this is a bit more complicated and then you must free the values.
A running C program doesn't use your variable names at all. Those names were useful for the compiler to build the program, but are discarded before you run it. This means that in C (but not in interpreted languages like python):
If you rename your variables, you get the exact same program
If you do strings <your program> you won't see any variable names (unless you retained debugging symbols)
Hence, runtime is too late to create new variables. In C, variables are compile-time only. Of course, you can use arrays, or dictionaries, to simulate run-time variable creation, like the other answer, and a few commenters, suggest.
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 8 years ago.
OMG, I know this should be extremely simple and I have tried everything I have researched but nothing works. I am missing something simple, please help. I just want to declare a string and then later compare it to another string.
I want to declare a key of something like 9 characters. Then I want to compare this string to another one submitted later. Below is what I have and no matter what I change I get errors from incompatible types to missing token.
char key[] ="kjherres";
char f[];
F="kjherres";
if (key==f) {
//run my code
}
I have also tried (strcmp) to no avail. What am I missing? Please help.
The way you compare strings is with the strcmp function.
if ( strcmp(key,f) == 0 ) {
/* strings are the same */
}
You should have a good book or online tutorial to learning C. If you're coming from PHP or some other high-level language, you have a LOT to learn and if you don't do it right, you're asking for big problems. Strings are not as trivial in C as they are in PHP etc.
Also, C is case-sensitive. F and f are different names.
OK, this was a stupid thing I missed as always. Sometimes my mind is going faster than my fingers.
What the problem was is that I assigned f from a url param but I was only reading the first char of the param. Forgive me for the ignorance, it can happen often when going too fast.
So, i've been commissioned to translate some fortran subroutines into C. These subroutines are being called as part of the control flow of a large porgram based primarily in C.
I am translating the functions one at a time, starting with the functions that are found at the top of call stacks.
The problem I am facing is the hand-off of array data from C to fortran.
Suppose we have declared an array in c as
int* someCArray = (int*)malloc( 50 * 4 * sizeof(int) );
Now, this array needs to be passed down into a fortran subroutine to be filled with data
someFortranFunc( someCArray, someOtherParams );
when the array arrives in fortran land, it is declared as a variable sized matrix as such:
subroutine somefortranfunc(somecarray,someotherparams)
integer somefarray(50,*)
The problem is that fortran doesn't seem to size the array correctly, becuase the program seg-faults. When I debug the program, I find that indexing to
somefarray(1,2)
reports that this is an invalid index. Any references to any items in the first column work fine, but there is only one available column in the array when it arrives in fortran.
I can't really change the fact that this is a variable sized array in fortran. Can anyone explain what is happening here, and is there a way that I can mitigate the problem from the C side of things?
[edit]
By the way, the fortran subroutine is being called from the replaced fortran code as
integer somedatastorage(plentybignumber)
integer someindex
...
call somefarray(somedatastorage(someindex))
where the data storage is a large 1d array. There isn't a problem with overrunning the size of the data storage. Somehow, though, the difference between passing the C array and the fortran (sub)array is causing a difference in the fortran subroutine.
Thanks!
Have you considered the Fortran ISO C Binding? I've had very good results with it to interface Fortran and C in both directions. My preference is to avoid rewriting existing, tested code. There are a few types that can't be transferred with the current version of the ISO C Binding, so a translation might be necessary.
What it shouldn't be that others suggested:
1. Size of int vs. size of Integer. Since the first column has the right values.
2. Row vs. column ordering. Would just get values in wrong order not segmentation faulted.
3. Reference vs value passing. Since the first column has the right values. Unless the compiler is doing something evil behind your back.
Are you sure you don't do this in some secret way?:
someCArray++
print out the value of the someCArray pointer right after you make it and right before you pass it. You also should print it out using the debugger in the fortran code just to verify that the compiler is not generating some temporary copies to help you.