demo_3_7
1 #define _CRT_SECURE_NO_WARNINGS 1 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <assert.h> 6 #include <stddef.h> 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<src || 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 }