1

I have basically two queries. First this code is working fine I just want to print the results and second this program enters only one record. I want to save a complete address book of a record like name contact. For that I will have to give separate struct pointer for every field? Please help me out.

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct node
{
   int data;
   struct node *link;
} *head=NULL;

void inserfirst();

int main()
{
    insertfirst();
    getch();
    return 0;
}

void insertfirst()
{
     int item;
     struct node *ptr;
     scanf("%d",&item);
     if (head==NULL) {
         head=(struct node*)malloc(sizeof(struct node));
         head->data=item;
         head->link=NULL;
     } else {
         ptr=head;
         head=(struct node*)malloc(sizeof(struct node));
         head->data=item;
         head->link=ptr;
     }
}
sunkehappy
  • 8,970
  • 5
  • 44
  • 65
  • You should indent ALL of your code by 4 spaces so people can see your code better – Travis Griggs Dec 08 '12 at 08:10
  • 1
    `head=(struct node*)malloc(sizeof(struct node));` is **plain wrong,** it should be `head = malloc(sizeof(*head));` (i. e. don't cast, use `sizeof(*pointer)` instead of `sizeof(type)` and use whitespace properly). –  Dec 08 '12 at 08:15
  • 2
    @H2CO3 what's wrong with `sizeof(type)`? And what's wrong with casting? It's more verbose and can be even necessary if C++ compiler is used (which is the case in 99%) – SomeWittyUsername Dec 08 '12 at 08:20
  • @icepack 1. No one is talking about C++, the question is tagged C. 2. Don't try to compile C++ as C, because they're different languages. 3. Don't use a C++ compiler which does not have a C-only mode. 4. The cast is not just more verbose, it explicitly decreases readability (casts are *ugly*). 5. It's redundant, since `void *` (the return value of `malloc()`) is explicitly compatible with any data pointer type. 6. It's dangerous if you forget to `#include `. Then `int` will be assumed as return type, and if `sizeof(int) != sizeof(void *)`, then it causes memory corruption once again. –  Dec 08 '12 at 08:25
  • 1
    @icepack 7. `sizeof(type)` **will** break when you change the type of the pointer (and you'll get more-than-hard-to-track-down segfaults). –  Dec 08 '12 at 08:25
  • @H2CO3 also have no problem with the type cast - makes for legibility. And sizeof(Type) is widely used and sometimes required (what if your pointer is a void*) - certainly not a huge issue. – Elemental Dec 08 '12 at 08:26
  • @Elemental wrong, wrong, wrong, wrong... You both are in the serious need of reading [this](http://www.kernel.org/doc/Documentation/CodingStyle), [this](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) and [this](http://stackoverflow.com/questions/7545365/why-does-this-code-segfault-on-64-bit-architecture-but-work-fine-on-32-bit). –  Dec 08 '12 at 08:28
  • @H2CO3 I think I understand the issues: the style guide explicitly says style is a matter of personal preference; the two stack overflow links both have conflicting opinions. Personally ONLY the 'what if you leave stdlib out' argument seems at all strong and basically *This is why you never compile without warnings about missing prototypes*. – Elemental Dec 08 '12 at 08:37
  • @Elemental the two SO answers do not have conflicting opinions, they both say basically what I advise as well. All of the 64 vs 32 bit, `sizeof(type)` vs. `sizeof(*ptr)` and "typecasting is redundant" arguments are valid and respected by most decent programmers, but go ahead and write buggy and unreadable code if you wish. –  Dec 08 '12 at 08:40
  • @H2CO3 First of all, writing **"plain wrong"** about the posted code is plain wrong. The code is correct despite your coding style preferences and disadvantages that such approach may or may not have. Second, C++ compiler is widely used for C code, whether you like it or not. Third, various compilers support various C standards - notable is MSVC with only C90 support. And finally, your links have serious discussions about the issues you raise (both casting and sizeof) - the conclusion is that there is no absolute answer and it depends on the specific situation. – SomeWittyUsername Dec 08 '12 at 08:44
  • @H2CO3 actually, I find it funny when people claim *"bla bla 1 will not work if you change bla bla 2"* - meaning it's acceptable to completely change *bla bla* but it's not ok to use C++ compiler which have stronger typing and can actually prevent bugs at compiler level that pure C compiler won't. – SomeWittyUsername Dec 08 '12 at 08:48
  • What is this error and how will it be removed? "Lvalue required" – Daniel Radcliffe Dec 08 '12 at 09:11
  • 1
    Regarding malloc()-casting in C++, earlier [this week](http://stackoverflow.com/questions/13677566/malloc-a-2d-array-in-c/13677636#13677636) I answered that very issue. I suppose so long as you're not using the features of the C language supported by the standard (VLAs for example) then go ahead and compile with C++. Of course, any self-respecting C++ programmer will use a vector<> in that case, but then that won't compile in C, now will it. Face it. They're different, and I blame the whole "move at your own pace from C to C++" bullshit people bought into hook, line, and sinker (and still do). – WhozCraig Dec 08 '12 at 09:31
  • The biggest problem is that i have to use c compiler i am in such a situation where i am not allowed to use any other compiler... – Daniel Radcliffe Dec 08 '12 at 09:44
  • 1
    @user1885560 all the better if you're mission is writing **C** code, sir. If you're mission is writing C-code that compiles with a C++ compiler, *they're different missions*. Obviously in your case, I wouldn't worry about. Dance with the one you brought. – WhozCraig Dec 08 '12 at 10:02
  • @WhozCraig There is an item pusblished long ago by MS that I personally find insightful. Among other things it discusses the subtlties and mentions the advantages of using C++ compiler for a C code in an environment that wasn't natively ready for C++: http://msdn.microsoft.com/en-us/library/windows/hardware/gg487420.aspx#EFC – SomeWittyUsername Dec 08 '12 at 18:36
  • @icepack I remember when that article came out, and it struck me somewhat odd that there were *no* "advantages" specified besides generic euphemisms and, of course, "stricter type checking", and even that was discussed as disadvantageous for otherwise-legal kernel driver code. The rest of the article dissects all the gotchas where using C++ as a "Super-C" in a driver environment can bite you in the ass. Funny that. For me, if one's goal is to write C++ compilable "C-code", so be it. Just like C-compilable "C++ code", you will be restricted on feature choice either way (the latter more-so). – WhozCraig Dec 08 '12 at 19:07
  • @WhozCraig Stricter type checking is a big issue. Not so long ago we moved our kernel code base to C++. The first step was, of course, the compilation. Not surprisingly, lots of **real** errors were discovered in pure C90 code, some are serious and some less. – SomeWittyUsername Dec 08 '12 at 20:02
  • @icepack yeah I wish the stds committees would just squeeze that, and *only* that, into the C std for good, without all the other C++ cruft. I love *both* languages, and there are some things I wish I could do in each from the other, but alas, not to be. – WhozCraig Dec 09 '12 at 02:09

2 Answers2

0

To address your issues:

In general the way would keep multiple bits of information (Name, numbers, address etc) is by including them in the node struct, something like:

struct node
{
   int data;
   char name[50];
   char phone[20];
   struct node *link;
} *head=NULL;

This is a list of contacts, each node has the contact details, the list contains multiple contacts.

To print such a list out one would iterate through the list and print each node, specifically:

  1. Start with the head
  2. if the current node is null then we're at the end so exit
  3. print of the content of the current node
  4. set the current node to the next node (i.e. current->link)
  5. go back to step 2
Elemental
  • 7,365
  • 2
  • 28
  • 33
  • that means i do not need to give a separate struct pointer for every field right? just one *link that will link to the next complete node... – Daniel Radcliffe Dec 08 '12 at 08:36
0

you can use this also

   typedef struct contact
    {
     int data;
    char name[40];
    char add[90];
    }book;
    stuct node
    {
    book b;
    struct node*link;
    }*head=NULL;
sushant goel
  • 821
  • 6
  • 8