views:

98

answers:

2

Hi, I'm writing to a text file using the following declaration:

void create_out_file(char file_name[],long double *z1){
    FILE *out;
    int i;

    if((out = fopen(file_name, "w+")) == NULL){
        fprintf(stderr, "***> Open error on output file %s", file_name);
        exit(-1);
    }

    for(i = 0; i < ARRAY_SIZE; i++)
    fprintf(out, "%.16Le\n", z1[i]);
    fclose(out);
}

Where z1 is an long double array of length ARRAY_SIZE. The calling function is:

create_out_file("E:/first67/jz1.txt", z1);

I defined the prototype as:

void create_out_file(char file_name[], long double z1[]);

which I'm putting before "int main" but after the preprocessor directives. My code works fine.

I was thinking of putting the prototype as

void create_out_file(char file_name[],long double *z1). 

Is this correct? *z1 will point to the first array element of z1.

Is my declaration and prototype good programming practice?

Thanks a lot...

Update: To make the program general, I defined ARRAY_SiZE as:

const int ARRAY_SIZE = 11;

The prototype becomes:

void create_out_file(const char *file_name, const long double *z1, size_t z_size)

the called function is:

create_out_file("/tmp/myname", z1, ARRAY_SIZE);

and in the function declaration I have

void create_out_file(const char *file_name, const long double *z1, size_t z_size)

FILE *out;
int i;
    if((out = fopen(file_name, "w+")) == NULL){
    fprintf(stderr, "***> Open error on output file %s", file_name);
    exit(-1);
    }


for(i = 0; i < z_size; i++)
fprintf(out, "%.16Le\n", z1[i]);
fclose(out);
}

Will this work?

New Update On compilation, for the line

for(i = 0; i < z_size; i++)

in the declaration, I get the warning: : warning C4018: '<' : signed/unsigned mismatch

What's wrong here?

Thanks...

Latest news: It's working fine thanks to Jonathan Leffler

A: 

declarations: long double z1[] and long double *z1 are completely same.

*z1 will point to the first array element of z1

yes. there is no such entity array in c. There are only pointers and some thin syntax sugar for accessing them [ ].

Andrey
Thanks for the clarifications.
yCalleecharan
"There is no such entity array in c". Not true. Most array operations are implemented through array-to-pointer decay - that's true. But to say that all arrays are just pointers is completely incorrect.
AndreyT
@AndreyT - yes, i say it again - there is no such entity array in C. let me explain. i tell that entity is defined if two conditions match - there is special notation for it (there is in C) and there are operations defined. here it is not true. no operation except accessing by index are defined, and that one is translated into pointer operation. there are no arrays - there is a memory and pointers. and some very thin syntax sugar.
Andrey
Thanks for the interesting discussions.
yCalleecharan
AndreyT
This is often described as a difference between *object context* and *value context*. In a value context array acts as a pointer. In object context array acts as an array, not as a pointer. Because of its behavior in the object context, it is absolutely incorrect to say that array is a pointer.
AndreyT
+1  A: 

Use 'const char file_name[]' or 'const char *file_name' - you aren't going to change the name in the function.

Likewise, use 'const long double *z1' or 'const long double z1[]'.

The choice between pointer and array notation in a function prototype is largely arbitrary. I almost always use the pointer notation - because ultimately that is what is passed into the function. There are those who argue that if you are going to use the pointer as an array, use the array notation; it is a perfectly reasonable viewpoint - but not the one I use.

Your code is more general if you pass the array size into the function:

void create_out_file(const char *file_name, const long double *z1, size_t z_size)
{
    ...
}

Note that the choice between pointer and array notation is not arbitrary for global variables. There is a lot of difference between these two:

extern char *something;
extern char  anotherthing[];

One says there is a pointer-sized memory location that contains the address of a character string (presumably). The other says that there is a character string somewhere known by the name 'anotherthing', the value of which is a pointer. That may be a bit subtle - but the difference is crucial. The 'pointer == array' isomorphism only applies in function argument lists.

Jonathan Leffler
Thanks. I'm trying to make it general so that I can write different sized arrays to different text files. You added: size_t z_size. Is this just one variable? I need to change ARRAY_SIZE to size_t z_size so that we write to the the correct length?
yCalleecharan
@yCalleecharan: `size_t` is a standard type that is big enough to hold the size of an object defined in several standard headers - `<stddef.h>`, `<stdlib.h>`, `<stdio.h>` to name but 3. If ARRAY_SIZE is a macro, it can be used in the function call if there's a prototype in scope. The compiler will convert it to `size_t` for you. (You're unlikely to run into trouble even without a prototype, but don't give yourself unnecessary problems.) So yes, `z_size` (or `z1_size`) is a single variable of type `size_t` passed to the function: `create_out_file("/tmp/myname", z1, ARRAY_SIZE);`
Jonathan Leffler
Thanks a lot. Please see my updated post and can you please tell me if I'm understanding you correctly.
yCalleecharan
@yCalleecharan: yes, that is what I was suggesting. I've not scrutinized the code, but the extra parameter is present and used in the expected location.
Jonathan Leffler
Thanks again. I get a warning message though. I put the information up in the post. Can you please take a look at it?
yCalleecharan
@yCalleecharan: size_t is an unsigned type; ssize_t is the matching signed type; int i is a signed type; the complaint is technically correct, but practically almost pointless. However, you do not want the compiler complaining. You have two main alternatives: (1) use ssize_t as the argument (and maybe assert that z_size > 0 and z_size < some suitably large positive value), and (2) use 'size_t i;' instead of 'int i;'. I usually use option (2).
Jonathan Leffler
Hi, I've tried the easy second option and I don't have any warnings now. My sincere gratitude to you for your very kind help. Can you please recommend me C books which are good to read. From what I know C books written prior to year 2000 are usually better.
yCalleecharan
I learned C from 'K it is a book to learn programming in C given that you know how to program in some other language. The main supplemental book that I have for C is ["C: A Reference Manual (5th Edn)"](http://www.careferencemanual.com/). Otherwise, I look at a number of the general programming books: The Practice of Programming (Kernighan and Pike) is good; The Art of UNIX Programming (Raymond) is too.
Jonathan Leffler
yCalleecharan