1 #define _CRT_SECURE_NO_WARNINGS 1
2 #include
3 #include
4 #include <string.h>
5 #include
6 #include
7
8
9 //内存拷贝函数
10 void my_memcpy(void* dest, void* src, size_t count)
11 {
12 char* ret = dest;
13 assert(dest != NULL);//断言,不为零
14 assert(src != NULL);//断言
15 int i = count;
16 while (i--)
17 {
18 *(char*)dest = *(char*)src;
19 ++(char*)dest;
20 ++(char*)src;
21 }
22 return ret;
23 }
24 int main()
25 {
26 int arr1[] = { 1, 2, 3, 4, 5 };
27 int arr2[10] = { 0 };
28 //arr1中的数字拷贝
29 my_memcpy(arr2, arr1, sizeof(arr1);;
30
31 system("pause");
32 return 0;
33 }
34
35
36 //重叠拷贝函数
37 void* my_memmove(void* dest, const void* src, size_t count)
38 {
39 void* ret = dest;
40 assert(dest != NULL);
41 assert(src != NULL);
42 if (dest(char*)src + count)
43 {
44 //从前向后拷贝
45
46 }
47 else{
48 //从后向前拷贝
49
50 }
51
52 }
53 void* my_memmove(void* dest, const void* src, size_t count)
54 {
55 void* ret = dest;
56 assert(dest != NULL);
57 assert(src != NULL);
58 if (dest < src)
59 {
60 //前->后
61 while (count--)
62 {
63 *(char*)dest = *(char*)src;
64 ++(char*)dest;
65 ++(char*)src;
66 }
67 }
68 else{
69 //后->前
70 while (count--)
71 {
72 *((char*)dest + count) = *((char*)src+count);
73
74 }
75 }
76 return ret;
77 }
78 int main()
79 {
80 int arr3[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
81 //my_memcpy不能胜任重叠拷贝的
82 //my_memcpy(arr3+2,arr3,20);
83
84 //memmove可以胜任内存的重叠拷贝
85 //memmove既可以处理重叠也可以处理不重叠
86 my_memmove(arr3 + 2, arr3, 20);
87
88 //C语言标准中,memcpy函数可以拷贝不重叠的
89 //当下发现,vs2013环境下的memcpy可以处理重叠拷贝
90 memcpy(arr3 + 2, arr3, 20);
91
92 system("pause");
93 return 0;
94 }
95
96
97 //内存比较函数 - memcmp
98 int main()
99 {
100 int arr1[] = { 1, 2, 3, 4, 5 };
101 int arr2[] = { 1, 2, 5, 4, 3 };
102 //memcmp比较内存大小的函数
103 int ret = memcmp(arr1, arr2, 8);
104 printf("%d\n", ret);
105 system("pause");
106 return 0;
107 }
108
109
110 //内存设置函数 - memset
111 //设置缓冲区为一个特定的字符
112 int main()
113 {
114 char arr[10] = "";
115 int arr[10] = { 0 };
116 memset(arr, 1, 10);//把arr中10个字节的内存空间设置为1
117 memset(arr, '#', 10);
118
119 system("pause");
120 return 0;
121 }
122
123
124 //声明一个结构体,定义一个结构体变量
125 //声明一个学生类型,想通过学生类型来创建学生对象或变量的
126 //描述学生 - 属性 - 名字 - 电话 - 性别 - 年龄
127 struct Stu
128 {
129 char name[20];//名字
130 char tele[12];//电话
131 char sex[10];//性别
132 int age;
133 }s4,s5,s6;//全局结构体变量
134 //创建全局变量
135 struct Stu s3;
136 int main()
137 {
138 //创建的是结构体变量
139 struct Stu s1;//局部变量
140 struct Stu s2;
141
142 system("pause");
143 return 0;
144 }
145
146 //匿名结构体类型 - 没有名字
147 struct
148 {
149 int a;
150 char c;
151 }sa;
152 //匿名结构体指针类型
153 //类型不统一是不能存放数据的
154 //编译器会把这两个声明当成完全不同的两个类型,所以是非法的
155 struct
156 {
157 int a;
158 char c;
159 }* psa;
160 int main()
161 {
162 system("pause");
163 return 0;
164 }
165
166 //结构体的自引用
167 struct Node
168 {
169 int data;
170 //存放下一个节点的地址
171 struct Node* next;
172 };
173 int main()
174 {
175
176 system("pause");
177 return 0;
178 }
179
180 typedef struct Node
181 {
182 int data;
183 struct Node* next;
184 }Node;
185 int main()
186 {
187 struct Node n1;
188 Node n2;
189
190 system("pause");
191 return 0;
192 }
193
194 //结构体变量的定义和初始化
195 struct T
196 {
197 double weight;
198 short age;
199 };
200 struct S
201 {
202 char c;
203 int a;
204 double d;
205 char arr[20];
206 struct T st;//结构体可以包含结构体
207 };
208 int main()
209 {
210 //struct S s = { 'c', 100, 3.14, "hello bit" };//结构体的初始化
211 struct S s = { 'c', { 55.6, 30 }, 100, 3.14, "hello bit" };
212 printf("%c %d %lf %s\n", s.c, s.a, s.d, s.arr);//结构体的访问
213 printf("%lf\n", s.st.weight,s.st.age);
214 system("pause");
215 return 0;
216 }
217
218 //结构体内存对齐
219 struct S1
220 {
221 char c1;
222 int a;
223 char c2;
224 };
225 struct S2
226 {
227 char c1;
228 char c2;
229 int a;
230 };
231 struct S3
232 {
233 double d;
234 char c;
235 int i;
236 };
237 struct S4
238 {
239 char c1;
240 struct S3 s3;//嵌套
241 double d;
242 };
243 int main()
244 {
245 struct S1 s1 = { 0 };//第一个给0,剩下的都初始化为0
246 printf("%d\n", sizeof(s1));//12
247 struct S2 s2 = { 0 };
248 printf("%d\n", sizeof(s2));//8
249 struct S3 s3 = { 0 };
250 printf("%d\n", sizeof(s3));//16
251 struct S4 s4 = { 0 };
252 printf("%d\n", sizeof(s4));//32
253 system("pause");
254 return 0;
255 }
256
257 //设置默认对齐数为4
258 #pragma pack(4)
259 struct S
260 {
261 char c1;//1个字节
262 double d;//8个字节s
263 };
264 //取消设置的默认的对齐数
265 #pragma pack()
266
267 //设置默认对齐数为1,任何字节都可以往里放
268 #pragma pack(1)
269 struct S
270 {
271 char c1;//1个字节
272 double d;//8个字节s
273 };
274 //取消设置的默认的对齐数
275 #pragma pack()
276
277 int main()
278 {
279 struct S s;
280 printf("%d\n", sizeof(s));
281 }
282
283 struct S
284 {
285 char a;
286 int b;
287 double c;
288 };
289 int main()
290 {
291
292 //offsetof - 偏移量
293 printf("%d\n",offsetof(struct s,a));//传的是类型
294 printf("%d\n", offsetof(struct s, b));
295 printf("%d\n", offsetof(struct s, c));
296 system("pause");
297 return 0;
298 }
299
300
301 //结构体传参
302 struct S
303 {
304 int a;
305 char c;
306 double d;
307 };
308 void Init(struct S* ps)
309 {
310 //结构体传参传的是地址
311 ps->a = 100;
312 ps->c = 'w';
313 ps->d = 3.14;
314 }
315 void Print1(struct S tmp)
316 {
317 //结构体传的是值
318 printf("%d %c %lf\n", tmp.a, tmp.c, tmp.d);
319 }
320 void Print2(const struct S*ps)
321 {
322 //传地址
323 printf("%d %c %lf\n", ps->a, ps->c, ps->d);
324 }
325 int main()
326 {
327 struct S s;
328 Init(&s);//传地址
329 Print1(s);//传值
330 Print2(&s);
331 //值传递是一份临时拷贝
332
333 //s.a = 100;
334 //s.c = 'w';
335 //s.d = 3.14;//直接操作结构体变量
336 //所有的操作在主函数中操作(目前)
337 system("pause");
338 return 0;
339 }
340
341 //位段 - 位 - 二进制位
342 //定义位段
343 struct S
344 {
345 int a : 2;//2个比特位
346 int b : 5;//5个比特位
347 int c : 10;//10个比特位
348 int d : 30;//30个比特位
349 //47个比特位 - 6个字节*8=48个比特位
350 //位段数只能在允许的范围内,否则报错
351 };
352 int main()
353 {
354 struct S s;
355 printf("%d\n", sizeof(s));
356 system("pause");
357 return 0;
358 }
359
360
361 struct S
362 {
363 //定义类型
364 char a : 3;
365 char b : 4;
366 char c : 5;
367 char d : 4;
368 };
369 int main()
370 {
371 //使用这个类型
372 struct S s = { 0 };
373 s.a = 10;
374 s.b = 20;
375 s.c = 3;
376 s.d = 4;
377 system("pause");
378 return 0;
379 }