UNIT-4 Structures and Unions Q.1 What will be the output of the following program? struct { int i; float f; }var; int main() { var.i=5; var.f=9.76723; printf("%d %.2f”,var.i,var.f); return(0); } (a) Compile-Time Error (b) 5 9.76723 (c) 5 9.76 (d) 5 9.77 Q.2 What will be the output of the following program? int main() { int val=1234; int* ptr=&val; printf(“%d %d”,val,*ptr++); return(0); } (a) Compile-Time Error (b) 5 9.76723 (c) 5 9.76 (d) 5 9.77 Q.3 What will be the output of the following program? struct values { int i; float f; }; int main() { struct values var={555,67.05501}; printf(“%2d %.2f”,var.i,var.f); return(0); }

(a) 1234 1234 (b) 1235 1235 (c) 1234 1235 (d) 1235 1234 Q.4 What will be the output of the following program? typedef struct { int i; float f; }values; int main() { static values var={555,67.05501}; printf(“%2d %.2f”,var.i,var.f); return(0); } (a) Compile-Time Error (b) 55 67.05 (c) 555 67.06 (d) 555 67.05 Q.5 What will be the output of the following program? struct my_struct { int i=7; float f=999.99; }var; int main() { var.i=5; printf(“%d %.2f”,var.i,var.f); return(0); (a) Compile-Time Error (b) 7 999.99 (c) 5 999.99 (d) None of these Q.6 What will be the output of the following program? struct first { int a; float b; }s1={32760,12345.12345}; typedef struct { char a; int b; }second; struct my_struct { float a; unsigned int b; 80

}; typedef struct my_struct third; int main() { static second s2={‘A’,- -4}; third s3; s3.a=~(s1.a-32760); s3.b=-++s2.b; printf(“%d %.2f\n%c %d\n%.2f %u”,(s1.a)--,s1.b+0.005,s2.a+32,s2.b,++(s3.a),-s3.b); return(0); } (a) Compile-Time Error (b) 32760 12345.12 A4 1 -5 (c) 32760 12345.13 a -5 0.00 65531 (d) 32760 12345.13 a5 0.00 65530 Q.7 What will be the output of the following program? struct { int i,val[25]; }var={1,2,3,4,5,6,7,8,9},*vptr=&var; int main() { printf(“%d %d %d\n”,var.i,vptr->i,(*vptr).i); printf(“%d %d %d %d %d %d”,var.val[4],*(var.val+4),vptr>val[4],*(vptr->val+4),(*vptr).val[4],*((*vptr).val+4)); return(0); } (a) Compile-Time Error (b) 1 1 1 666666 (c) 1 1 1 555555 (d) None of these 81

Q.8 What will be the output of the following program? typedef struct { int i; float f; }temp; void alter(temp *ptr,int x,float y) { ptr->i=x; ptr->f=y; } int main() { temp a={111,777.007}; printf(“%d %.2f\n”,a.i,a.f); alter(&a,222,666.006); printf(“%d %.2f”,a.i,a.f); return(0); } (a) Compile-Time error (b) 111 777.007 222 666.006 (c) 111 777.01 222 666.01 (d) None of these Q.9 What will be the output of the following program? typedef struct { int i; float f; }temp; temp alter(temp tmp,int x,float y) { tmp.i=x; tmp.f=y; return tmp; } int main() { temp a={111,777.007}; 82

printf(“%d %.3f\n”,a.i,a.f); a=alter(a,222,666.006); printf(“%d %.3f”,a.i,a.f); return(0); } (a) Compile-Time error (b) 111 777.007 222 666.006 (c) 111 777.01 222 666.01 (d)None of these Q.10 What will be the output of the following program? typedef struct { int i; float f; }temp; temp alter(temp *ptr,int x,float y) { temp tmp=*ptr; printf(“%d %.2f\n”,tmp.i,tmp.f); tmp.i=x; tmp.f=y; return tmp; } int main() { temp a={65535,777.777}; a=alter(&a,-1,666.666); printf(“%d %.2f”,a.i,a.f); return(0); } (a) Compile-Time error (b) 65535 777.777 -1 666.666 (c) 65535 777.78 -1 666.67 (d) -1 777.78 -1 666.67 Q.11 What will be the output of the following program? struct my_struct1 { int arr[2][2]; 83

}; typedef struct my_struct1 record; struct my_struct2 { record temp; }list[2]={1,2,3,4,5,6,7,8}; int main() { int i,j,k; for (i=1; i>=0; i--) for (j=0; j<2; j++) for (k=1; k>=0; k--) printf(“%d”,list[i].temp.arr[j][k]); return(0); } (a) Compile-Time Error (b) Run-Time Error (c) 65872143 (d) 56781243 Q.12 What will be the output of the following program? struct my_struct { int i; unsigned int j; }; int main() { struct my_struct temp1={-32769,-1},temp2; temp2=temp1; printf(“%d %u”,temp2.i,temp2.j); return(0); } (a) 32767 -1 (b) -32769 -1 (c) -32769 65535 (d) 32767 65535 Q.14 What will be the output of the following program? struct names { char str[25]; struct names *next; }; typedef struct names slist; int main() { slist *list,*temp; 84

list=(slist *)malloc(sizeof(slist)); // Dynamic Memory Allocation strcpy(list->str,“Hai”); list->next=NULL; temp=(slist *)malloc(sizeof(slist)); // Dynamic Memory Allocation strcpy(temp->str,“Friends”); temp->next=list; list=temp; while (temp != NULL) { printf(“%s”,temp->str); temp=temp->next; } return(0); } (a) Compile-Time Error (b) HaiFriends (c) FriendsHai (d) None of these Q.14 What will be the output of the following program? (i) struct A { int a; struct B { int b; struct B *next; }tempB; struct A *next; }tempA; (ii) struct B { int b; struct B *next; }; struct A { int a; struct B tempB; struct A *next; }; (iii) struct B { int b; }tempB; 85

struct { int a; struct B *nextB; }; (iv) struct B { int b; struct B { int b; struct B *nextB; }tempB; struct B *nextB; }tempB; (a) (iv) Only (b) (iii) Only (c) All of the these (d) None of these Q.15 What will be the output of the following program? union A { char ch; int i; float f; }tempA; int main() { tempA.ch=‘A’; tempA.i=777; tempA.f=12345.12345; printf(“%d”,tempA.i); return(0); } (a) Compile-Time Error (b) 12345 (c) Erroneous output (d) 777 Q.16 What will be the output of the following program? struct A { int i; float f; union B { char ch; int j; 86

}temp; }temp1; int main() { struct A temp2[5]; printf(“%d %d”,sizeof temp1,sizeof(temp2)); return(0); } (a)6 30 (b)8 40 (c)9 45 (d)None of these Q.17 What will be the output of the following program? int main() { static struct my_struct { unsigned a:1; unsigned b:2; unsigned c:3; unsigned d:4; unsigned :6; // Fill out first word }v={1,2,7,12}; printf(“%d %d %d %d“,v.a,v.b,v.c,v.d); printf(“\nSize=%d bytes”,sizeof v); return(0); } (a) Compile-Time Error (b) 1 2 7 12 Size=2 bytes (c) 1 2 7 12 Size=4 bytes (d)None of these Q.18 What are the largest values that can be assigned to each of the bit fields defined in Q.17 above? (a) a=0 b=2 c=3 d=4 (b) a=1 b=2 c=7 d=15 (c) a=1 b=3 c=7 d=15 (d) None of these Q.19 What will be the output of the following program? int main() { struct sample { unsigned a:1; unsigned b:4; 87

}v={0,15}; unsigned *vptr=&v.b; printf(“%d %d”,v.b,*vptr); return(0); } (a) Compile-Time Error (b) 0 0 (c) 15 15 (d) None of these Q.20 What will be the output of the following program? int main() { static struct my_struct { unsigned a:1; int i; unsigned b:4; unsigned c:10; }v={1,10000,15,555}; printf(“%d %d %d %d”,v.i,v.a,v.b,v.c); printf(“\nSize=%d bytes”,sizeof v); return(0); } (a) Compile-Time Error (b) 1 10000 15 555 Size=4 bytes (c) 10000 1 15 555 Size=4 bytes (d) 10000 1 15 555 Size=5 bytes Solutions A.1 (d) Though both <struct type name> and <structure variables> are optional, one of the two must appear. In the above program, <structure variable>, i.e., var is used. (2 decimal places or) 2-digit precision of 9.76723 is 9.77 A.2 (d) Both <struct type name> and <structure variables> are optional. Thus, the structure defined in the above program has no use and the program executes in the normal way. A.3 (c) The members of a structure variable can be assigned initial values in much the same 88

manner as the elements of an array. The initial values must appear in order in which they will be assigned to their corresponding structure members, enclosed in braces and separated by commas. A.4 (c) In the above program, values is the user-defined structure type or the new user-defined data type. Structure variables can then be defined in terms of the new data type. A.5 (a) The C language does not permit the initialization of individual structure members within the template. The initialization must be done only in the declaration of the actual variables. The correct way to initialize the values is shown in A.3 or A.4. A.6 (d) Illustrating 3 different ways of declaring the structures: first, second and third are the user-defined structure type. s1, s2 and s3 are structure variables. Also, an expression of the form ++variable.member is equivalent to ++(variable.member), i.e., the ++ operator will apply to the structure member, not the entire structure variable. A.7 (b) The value of the member ‘i’ can be accessed using var.i, vptr->i and (*vptr).i Similarly, the 5th value of the member ‘val’ can be accessed using var.val[4], *(var.val+4), vptr->val[4], *(vptr->val+4), (*vptr).val[4] and *((*vptr).val+4) A.8 (c) This program illustrates the transfer of a structure to a function by passing the structure‘s address (a pointer) to the function. A.9 (b) This program illustrates the transfer of a structure to a function by value. Also, the altered structure is now returned directly to the calling portion of the program. A.10 (d) This program illustrates the transfer of a structure to a function by passing the structure’s address (a pointer) to the function. Also, the altered structure is now returned directly to the calling portion of the program. A.11 (c) This program illustrates the implementation of a nested structure, i.e., a structure inside another structure. A.12(d) An entire structure variable can be assigned to another structure variable, provided both variables have the same composition. A.13 (c) It is sometimes desirable to include within a structure one member, i.e,. a pointer to the parent structure type. Such structures are known as self-referential structures. 89

A.14 A.15

A.16

A.17

A.18

A.19

A.20

These structures are very useful in applications that involve linked data structures, such as lists and trees. [A linked data structure is not confined to some maximum number of components. Rather, the data structure can expand or contract in size as required.] (d) Since all the above structure declarations are valid in C. (c) The above program produces erroneous output (which is machine dependent). In effect, a union creates a storage location that can be used by any one of its members at a time. When a different member is assigned a new value, the new value supersedes the previous member’s value. [NOTE: The compiler allocates a piece of storage that is large enough to hold the largest variable type in the union, i.e., all members share the same address.] (b) Since int (2 bytes) + float (4 bytes) = (6 bytes) + Largest among union int (2 bytes) is equal to (8 bytes). Also, the total number of bytes in the array ‘temp2’ requires (8 bytes) * (5 bytes) = (40 bytes) (b) The four fields within ‘v’ require a total of 10 bits and these bits can be accommodated within the first word (16 bits). Unnamed fields can be used to control the alignment of bit fields within a word of memory. Such fields provide padding within the word. [NOTE: Some compilers order bit-fields from right-to-left (i.e., from lower-order bits to higher-order bits) within a word, whereas other compilers order the fields from left-to-right (higher-order to lower-order bits). (c) a=1 (1 bit: 0 or 1) b=3 (2 bits: 00 or 01 or 10 or 11), c=7 (3 bits: 000 or 001 or 010 or 011 or 100 or 101 or 110 or 111) d=15 (4 bits: 0000 or 0001 or 0010 or 0011 or 0100 or 0101 or 0110 or 0111 or 1000 or 1001 or 1010 or 1011 or 1100 or 1101 or 1110 or 1111) (a) Since we cannot take the address of a bit field variable, i.e., use of pointer to access the bit fields is prohibited. Also, we cannot use the scanf() function to read values into a bit field as it requires the address of a bit field variable. Also, array of bitfields are not permitted and a function cannot return a bit field. (d) Here, the bit field variable ‘a’ will be in the first byte of one word, the variable ‘i’ will be in the second word and the bit fields ‘b’ and ‘c’ will be in the third word. The variables ‘a’, ‘b’ and ‘c’ would not get packed into the same word. [NOTE: one word=2 bytes] 90

Structures, Unions, and Enumerations Q.1

What’s the difference between these two declarations? struct x1 { ... }; typedef struct { ... } x2; Ans: The first form declares a ‘structure tag’; the second declares a ‘typedef’. The main difference is that you subsequently refer to the first type as struct x1 and the second simply as x2.That is, the second declaration is of a slightly more abstract type-its users don’t necessarily know that it is a structure, and the keyword struct is not used when declaring instances of it. Q.2 Why doesn’t the following code work? struct x { ... }; x thestruct; Ans: C is not C++. Typedef names are not automatically generated for structure tags. Q.3 Can a structure contain a pointer to itself? Ans: Most certainly. Q. 4 What’s the best way of implementing opaque (abstract) data types in C? Ans: One good way is for clients to use structure pointers (perhaps additionally hidden behind typedefs) which point to structure types which are not publicly defined. Q.5 I came across some code that declared a structure like this: struct name { int namelen; char namestr[1]; }; and then did some tricky allocation to make the namestr array act like it had several elements. Is this legal or portable? Ans: This technique is popular, although Dennis Ritchie has called it ‘unwarranted chumminess with the C implementation’. An official interpretation has deemed that it is not strictly conforming to the C Standard, although it does seem to work under all known implementations. (Compilers which check array bounds carefully might issue warnings.) Another possibility is to declare the variable-size element very large, rather than very small; in the case of the above example: ... char namestr[MAXSIZE]; where MAXSIZE is larger than any name which will be stored. However, it looks like this technique is disallowed by a strict interpretation of the Standard as well. Furthermore, either of these ‘chummy’ structures must be used with care, since the programmer knows more about their size than the compiler does. (In particular, 91

they can generally only be manipulated via pointers.)C9X will introduce the concept of a ‘flexible array member’, which will allow the size of an array to be omitted if it is the last member in a structure, thus providing a well-defined solution. Q.6 Is there a way to compare structures automatically? Ans: No. There is no single, good way for a compiler to implement implicit structure comparison (i.e., to support the == operator for structures) which is consistent with C’s low-level flavor. A simple byte-by-byte comparison could founder on random bits present in unused ‘holes’ in the structure (such padding is used to keep the alignment of later fields correct; A field-by-field comparison might require unacceptable amounts of repetitive code for large structures. If you need to compare two structures, you’ll have to write your own function to do so, field by field. Q.7 How can I pass constant values to functions which accept structure arguments? Ans: As of this writing, C has no way of generating anonymous structure values. You will have to use a temporary structure variable or a little structure-building function. The C9X Standard will introduce ‘compound literals’; one form of compound literal will allow structure constants. For example, to pass a constant coordinate pair to a plotpoint() function which expects a struct point, you will be able to call plotpoint((struct point){1, 2});Combined with ‘designated initializers’ (another C9X feature), it will also be possible to specify member values by name:plotpoint((struct point){.x=1, .y=2}); Q.8 How can I read/write structures from/to data files? Ans: It is relatively straightforward to write a structure using fwrite():fwrite(&somestruct, sizeof somestruct, 1, fp); and a corresponding fread() invocation can read it back in. However, data files so written will *not* be portable. Note also that if the structure contains any pointers, only the pointer values will be written, and they are most unlikely to be valid when read back in. Finally, note that for widespread portability you must use the “b” flag when fopening() the files; A more portable solution, though it’s a bit more work initially, is to write a pair of functions for writing and reading a structure, field-by-field, in a portable (perhaps even human- readable) way. Q.9 My compiler is leaving holes in structures, which is wasting space and preventing ‘binary’ I/O to external data files. Can I turn off the padding, or otherwise control the alignment of structure fields? Ans: Your compiler may provide an extension to give you this control (perhaps a #pragma; but there is no standard method. Q.10 Why does sizeof() report a larger size than I expect for a structure type, as if there were padding at the end? Ans: Structures may have this padding (as well as internal padding), if necessary, to ensure that alignment properties will be preserved when an array of contiguous struc92

tures is allocated. Even when the structure is not part of an array, the end padding remains, so that sizeof() can always return a consistent size. Q.11 How can I determine the byte offset of a field within a structure? Ans: ANSI C defines the offsetof() macro, which should be used if available; see < stddef.h>. If you don’t have it, one possible implementation is #define offsetof(type, mem) ((size_t) \ ((char *)&((type *)0) > mem - (char *)(type *)0))This implementation is not 100% portable; some compilers may legitimately refuse to accept it. Q.12 How can I access structure fields by name at run time? Ans: Build a table of names and offsets, using the offsetof() macro. The offset of field b in struct a is offsetb = offsetof(struct a, b) If structp is a pointer to an instance of this structure, and field b is an int (with offset as computed above), b’s value can be set indirectly with *(int *)((char *)structp + offsetb) = value; Q.13 This program works correctly, but it dumps core after it finishes. Why? struct list { char *item; struct list *next; } /* Here is the main program. */ main(argc, argv) { ... } Ans: A missing semicolon causes main() to be declared as returning a structure. (The connection is hard to see because of the intervening comment.) Since structurevalued functions are usually implemented by adding a hidden return pointer, the generated code for main() tries to accept three arguments, although only two are passed (in this case, by the C start-up code). Q.14 Can I initialize unions? Ans: The current C Standard allows an initializer for the first-named member of a union. C9X will introduce ‘designated initializers’ which can be used to initialize any member. Q.15 What is the difference between an enumeration and a set of preprocessor #defines? Ans: At the present time, there is little difference. The C Standard says that enumerations may be freely intermixed with other integral types, without errors. (If, on the other hand, such intermixing were disallowed without explicit casts, judicious use of enumerations could catch certain programming errors.)Some advantages of enumerations are that the numeric values are automatically assigned, that a debugger may be able to display the symbolic values when enumeration variables are examined, and that they obey block scope. (A compiler may also generate non-fatal warnings when enumerations and integers are indiscriminately mixed, since doing so can still be 93

considered bad style even though it is not strictly illegal.) A disadvantage is that the programmer has little control over those non-fatal warnings; some programmers also resent not having control over the sizes of enumeration variables. Q.16 Is there an easy way to print enumeration values symbolically? Ans: No. You can write a little function to map an enumeration constant to a string. (For debugging purposes, a good debugger should automatically print enumeration constants symbolically. Q.14.What is the output of this program? struct num { int no; char name[25]; }; void main() { struct num n1[]={{25,“rose”},{20,”gulmohar”},{8,“geranium”},{11,“dahalia”}}; printf(“%d%d” ,n1[2].no,(*&n1+2)->no+1); } Ans: 8 9 Q15. What is the output of this program? struct Foo { char *pName; }; main() { struct Foo *obj = malloc(sizeof(struct Foo)); clrscr(); strcpy(obj->pName,“Your Name”); printf(“%s”, obj->pName);}. Ans: Your Name Q16. What is the output of this program? struct Foo { char *pName; char *pAddress; }; main() { 94

Ans: Q.17

Ans: Q.18

Ans: Q.19

struct Foo *obj = malloc(sizeof(struct Foo)); clrscr(); obj->pName = malloc(100); obj->pAddress = malloc(100); strcpy(obj->pName,“Your Name”); strcpy(obj->pAddress, “Your Address”); free(obj); printf(“%s”, obj->pName); printf(“%s”, obj->pAddress); } printd Nothing, as after free(obj), no memory is there containing obj->pName & pbj->pAddress What is the output of this program? main() { char *a = “Hello ”; char *b = “World”; clrscr(); printf(“%s”, strcat(a,b)); } Hello World What is the output of this program? main() { char *a = “Hello”; char *b = “World”; clrscr(); printf(“%s”, strcpy(a,b)); } World, copies World on a, overwrites Hello in a. What is the output of this program? union u { struct st { int i : 4; int j : 4; int k : 4; int l; 95

}st; int i; }u; main() { u.i = 100; printf(“%d, %d, %d”,u.i, u.st.i, u.st.l); } Ans: 100, 4, 0 Q.20 What is the output of this program? union u { union u { int i; int j; }a[10]; int b[10]; }u; main() { printf(“n%d”, sizeof(u)); printf(“ %d”, sizeof(u.a)); // printf(“%d”, sizeof(u.a[4].i)); } Ans: 20, 200, error for 3rd printf()

96

Unit_A

UNIT-4 Structures and Unions 80 Q.7What will be the output of the following program? struct { int i,val[25]; }var={1,2,3,4,5,6,7,8,9},*vptr=...