#include <stdio.h> #include <string.h>
struct peple { char name[20]; int age; }; struct student { int s1; char s2; double s3; }s; int main() { struct peple zhangsan; strcpy(zhangsan.name,"張三"); //結構體中的數組要使用strcpy進行賦值;
zhangsan.age = 19; printf("%s,.%d\n",zhangsan.name,zhangsan.age);
// 結構體 . 訪問和 -> 訪問,實質上都是指針訪問呢,只是編譯器對此做了優化; // 下面是對 . 訪問的 指針式理解
s.s1 = 4; // int *p1 = (int *)&s; *p1 = 4;
s.s2 = 'e'; // char *p2 = (char *)((int)&s + 4); *p2 = 'e';
s.s3 = 3.3; // double *p3 = (double *)((int)&s + 8); *p3 = 3.3;
printf("%d, %c, %f\n",s.s1,s.s2,s.s3); int *p1 = (int *)&s; char *p2 = (char *)((int)&s + 4); double *p3 = (double *)((int)&s + 8); //這裏是 +8, 而不是 +5
printf("%d, %c, %f\n",*p1,*p2,*p3); return 0; }
#include <stdio.h> typedef struct E { // 共佔24字節 共佔9字節 共佔20字節 共佔24字節 共佔24字節
short i; // 2 2 2 2
short j; // 2 2 2 2
char m; // 1(1+3) 1 1(1+1) 1(1+3)
int n; // 4 4 4 4
struct A a; // 12 9 10 12
}E; #pragma pack() typedef struct { // 共佔9字節
short i; // 2
short j; // 2
char m; // 1
int n; // 4
}__attribute__((packed)) CC; // 1字節對齊 2字節對齊 4字節對齊 8字節對齊
struct mystruct111 { // 共佔12字節 共佔12字節 共佔12字節 共佔16字節
int a; // 4 4 4 4
char b; // 1 1 1 1
short c; // 2 2 2 2
short d; // 2 2 2 2
}__attribute__((aligned(8))) My111;
#include <stdio.h>
// TYPE是結構體類型,MEMBER是結構體中一個元素的元素名 // 這個宏返回的是member元素相對於整個結構體變量的首地址的偏移量,類型是int
#define offsetof(TYPE, MEMBER) (int)(&((TYPE *)0) -> MEMBER )
// ptr是指向結構體元素member的指針,type是結構體類型,member是結構體中一個元素的元素名 // 這個宏返回的就是指向整個結構體變量的指針,類型是(type *)
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) struct cc { char a; short b; int c; }; int main(void) { struct cc s; s.b = 12; struct cc *pS = NULL; short *p = &(s.c); pS = container_of(p, struct cc, c); printf("&s.a = %p\n", &s); //&s.a = 0xbfd88d44
printf("&s.c = %p\n", p); //&s.c = 0xbfd88d48
printf("&pS = %p\n",pS); //&pS = 0xbfd88d44
printf("&s.b = %p\n", &(s.b)); //&s.b = 0xbfd88d46
printf("&s.b = %p\n", &(pS->b)); //&s.b = 0xbfd88d48
printf("pS.b = %d\n", pS->b); //12
return 0; }
#include <stdio.h> union myunion { int a; float b; char c; double d; }; struct aa { char i; int j; double d; }a1; int main(void) { union myunion t1; t1.a = 1123477881; printf("value = %f.\n", t1.b); //123.456001
int a = 1123477881; printf("指針方式:%f.\n", *((float *)&a)); //123.456001
t1.a = 12; printf("s1.b = %d.\n", t1.b); printf("s1 = %d\n", sizeof(union myunion)); //8
printf("a1 = %d\n", sizeof(struct aa)); //16
return 0; }
#include <stdio.h> union endian //共用體都是從地地址開始訪問的
{ char i; int j; }s; //小端模式返回1,不然爲大端模式
int is_little_endian1(void) { s.j = 1; // 地址0的那個字節內是1(小端)或者0(大端)
return s.i; } int is_little_endian2(void) { int i = 1; char p = *((char *)(&i)); return p; } int main(void) { char i; // i = is_little_endian2(); //union測試
i = is_little_endian2(); //指針測試
if(i == 1) { printf("小端模式\n"); } else { printf("大端模式\n"); } return 0; }
#include <stdio.h>
//這個枚舉用來表示函數返回值,error表示錯誤,right表示正確
enum return_value { error = 12, //枚舉值是全局的,直接本身就能夠用;
right , //由於枚舉是全局的,因此全部的枚舉類型中,常量符號都不能相同
}; enum return_value func1(void) { enum return_value r1 = right; return (r1); } int main(void) { printf("error = %d\n", error); printf("right = %d\n", right); enum return_value s = func1(); if(s == error) { printf("函數執行錯誤\n"); } else { printf("函數執行正確\n"); } return 0; }