owned this note
owned this note
Published
Linked with GitHub
# struct & enum & union
## 1
What is the output of the following program?
```c
#include‹stdio.h›
int main()
{
struct site
{
char name[] = "GeeksforGeeks";
int no_of_pages = 200;
};
struct site *ptr;
printf("%d",ptr->no_of_pages);
printf("%s",ptr->name);
getchar();
return 0;
}
```
:::spoiler Answer
Compile Error. Note the difference between structure/union declaration and variable declaration. When you declare a structure, you actually declare a new data type suitable for your purpose. So you cannot initialize values as it is not a variable declaration but a data type declaration.
正確的寫法是:
```c
#include <stdio.h>
#include <stdlib.h>
int main() {
struct site {
int no_of_pages;
};
struct site a = {100};
struct site* ptr = &a;
printf("%d", ptr->no_of_pages);
getchar();
return 0;
}
```
:::
## 2
What is the output of the following program?
```c
int main()
{
enum{i=10,j=20,k=50};
printf("%d\n",++k);
return 0;
}
```
:::spoiler Answer
Output:
Program will not compile and give 1 error
Explanation:
Here, i, j and k are inside the enum and therefore, they are like constants. In other words, if want to use 10 anywhere in the program, we can use i instead. In the first printf, the value of k is being modified which is not allowed because it’s enum constant.
[click here to see more information on enum](https://en.cppreference.com/w/c/language/enum)
:::
## 3
Explain “struct” and “union”
:::spoiler Answer
From [Struct declaration](https://en.cppreference.com/w/c/language/struct)
> A struct is a type consisting of a sequence of members whose storage is allocated in an ordered sequence (as opposed to union, which is a type consisting of a sequence of members whose storage overlaps).
struct 在 C 上是一種資料型態裡面可以包含多種資料型態,並且會按照程式中定義時擺放的順序在內存中排序,按照宣告的順序擺放。編譯器會自動為 struct 的成員分配空間。
在 C++ 上 struct 被擴展到可以內建 method ,跟 class 的意義非常類似,只是繼承與存取權限預設皆為 public 相反的 class 預設為 private,以及 class 有 template 的擴充 struct 沒有。
union 是一種特殊的資料型態,所有內容都從內存開頭開始存取的資料型態,並且他的大小由內部最大的那個資料型態來定義。會用同一個存儲空間,只能存儲最後一個成員訊息。只給其中一個成員給值而使用其他值就會壞掉。
補充:
enum: C語言提供自定型態為 enum,是一組由識別字所代表的整數常數(不可變更其值)。除非特別指定,不然都是由0開始,接下來遞增1。ex:
```clike
enum week{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
```
:::
## 4
What is the output of the following program?
```clike
#include<stdio.h>
int main()
{
struct bitfield {
signed int a : 3;
unsigned int b : 13;
unsigned int c : 1;
};
struct bitfield bit1 = { 2, 14, 1 };
printf("%ld\n", sizeof(bit1));
printf("%d\n", bit1.a);
printf("%d\n", bit1.b);
printf("%d\n", bit1.c);
return 0;
}
```
:::spoiler Answer
Output:
4
2
14
1
Explaination:
- [C 語言的 bit-field](https://hackmd.io/@sysprog/c-bitfield)
首先因為 2 對應的是 `signed int a`,所以整個 struct 會被 allocate 4 bytes of memory,但 `a` 只會站 3 個 bit,接下來 `b, c` 總共只用了 14 bits,不會超出原本既有的 4 btyes,因此 bit1 的 size 就是 4 bytes。
簡單來說,sturct 中有 bitfield 時,order matters!
- [How is the size of a struct with Bit Fields determined/measured?](https://stackoverflow.com/questions/4129961/how-is-the-size-of-a-struct-with-bit-fields-determined-measured)
:::
## 5
What is the output of the following program?
```clike
#include <stdio.h>
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
struct foo {
unsigned int a : 3;
unsigned int b : 2;
int : 0; /* Force alignment to next boundary */
unsigned int c : 4;
unsigned int d : 3;
};
int main() {
int i = 0xFFFF;
struct foo *f = (struct foo *) &i;
printf("%d\n", sizeof(f));
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
return 0;
}
```
:::spoiler Answer
Output:
8
a=7
b=3
c=4 (maybe anything)
d=6 (maybe anything)
Explaination:
- [C 語言的 bit-field](https://hackmd.io/@sysprog/c-bitfield)
:::
## 6
What is the output of the following program?
```clike
#include <stdio.h>
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
struct foo {
signed int a : 3;
signed int b : 2;
int : 0; /* Force alignment to next boundary */
signed int c : 4;
signed int d : 3;
};
int main() {
int i = 0xFFFF;
struct foo *f = (struct foo *) &i;
printf("%d\n", sizeof(f));
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
return 0;
}
```
:::spoiler Answer
Output:
8
a=-1
b=-1
c=4 (maybe anything)
d=-3 (maybe anything)
Explaination:
- [C 語言的 bit-field](https://hackmd.io/@sysprog/c-bitfield)
:::
## 7
What is the output of the following program?
```clike
#include<stdio.h>
int main()
{
typedef struct tag {
char str[10];
int a;
} har;
har h1, h2 = { "IHelp", 10 };
h1 = h2;
h1.str[1] = 'h';
printf("%s, %d\n", h1.str, h1.a);
printf("%s, %d\n", h2.str, h2.a);
return 0;
}
```
:::spoiler Answer
Output:
Ihelp, 10
IHelp, 10
Explaination:
用 C++ 的 move semantics 來想就很容易了。在 move semantics 之前,都是 hard copy,而 move semantics 就像是 shallow copy。
- [Structure Assignment and Its Pitfall in C Language](http://blog.zhangliaoyuan.com/blog/2013/01/28/structure-assignment-and-its-pitfall-in-C-language/)
:::
## 8
What is the output of the following program?
```clike
#include <stdio.h>
struct sample {
int a;
} sample;
int main()
{
sample.a = 100;
printf("%d", sample.a);
return 0;
}
```
:::spoiler Answer
Output: 100
:::