|
1 | 1 | --- |
2 | 2 | sidebar_position: 12 |
3 | | -title: (编写中)链表 |
| 3 | +title: (编写中)其他数据结构 |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | ## 链表 |
@@ -405,3 +405,226 @@ void deleteNodeList(Node *head, Node *find){ |
405 | 405 | free(find); |
406 | 406 | } |
407 | 407 | ``` |
| 408 | +
|
| 409 | +
|
| 410 | +
|
| 411 | +### 字符串的基本概念 |
| 412 | +
|
| 413 | +- 字符串是位于双引号中的字符序列 |
| 414 | +
|
| 415 | +* 在内存中以“\0”结束,所占字节比实际多一个例如:"Hello"在内存中存储为:"Hello\0"。 |
| 416 | +
|
| 417 | +### 字符串的初始化 |
| 418 | +
|
| 419 | +- 在 C 语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。 |
| 420 | +- 当把一个字符串存入一个数组时,会把结束符‘\0’存入数组,并以此作为该字符串是否结束的标志。 |
| 421 | +- 有了‘\0’标志后,就不必再用字符数组 的长度来判断字符串的长度了 |
| 422 | +- 初始化 |
| 423 | +
|
| 424 | +```c showLineNumbers |
| 425 | + char name[9] = "lnj"; //在内存中以“\0”结束, \0ASCII码值是0 |
| 426 | + char name1[9] = {'l','n','j','\0'}; |
| 427 | + char name2[9] = {'l','n','j',0}; |
| 428 | + // 当数组元素个数大于存储字符内容时, 未被初始化的部分默认值是0, 所以下面也可以看做是一个字符串 |
| 429 | + char name3[9] = {'l','n','j'}; |
| 430 | +``` |
| 431 | + |
| 432 | +- 错误的初始化方式 |
| 433 | + |
| 434 | +```c showLineNumbers |
| 435 | + //省略元素个数时, 不能省略末尾的\n |
| 436 | + // 不正确地写法,结尾没有\0 ,只是普通的字符数组 |
| 437 | + char name4[] = {'l','n','j'}; |
| 438 | + |
| 439 | + // "中间不能包含\0", 因为\0是字符串的结束标志 |
| 440 | + // \0的作用:字符串结束的标志 |
| 441 | + char name[] = "c\0ool"; |
| 442 | + printf("name = %s\n",name); |
| 443 | +输出结果: c |
| 444 | +``` |
| 445 | +
|
| 446 | +### 字符串输出 |
| 447 | +
|
| 448 | +- 如果字符数组中存储的是一个字符串, 那么字符数组的输入输出将变得简单方便。 |
| 449 | +
|
| 450 | +* 不必使用循环语句逐个地输入输出每个字符 |
| 451 | +* 可以使用 printf 函数和 scanf 函数一次性输出输入一个字符数组中的字符串 |
| 452 | +
|
| 453 | +- 使用的格式字符串为“%s”,表示输入、输出的是一个字符串 字符串的输出 |
| 454 | +- **输出** |
| 455 | +
|
| 456 | +* %s 的本质就是根据传入的 name 的地址逐个去取数组中的元素然后输出,直到遇到\0 位置 |
| 457 | +
|
| 458 | +```c showLineNumbers |
| 459 | +char chs[] = "lnj"; |
| 460 | +printf("%s\n", chs); |
| 461 | +``` |
| 462 | + |
| 463 | +- 注意点: |
| 464 | + |
| 465 | +* \0 引发的脏读问题 |
| 466 | + |
| 467 | +```c showLineNumbers |
| 468 | +char name[] = {'c', 'o', 'o', 'l' , '\0'}; |
| 469 | +char name2[] = {'l', 'n', 'j'}; |
| 470 | +printf("name2 = %s\n", name2); // 输出结果: lnjcool |
| 471 | +``` |
| 472 | +- **输入** |
| 473 | +
|
| 474 | +```c showLineNumbers |
| 475 | +char ch[10]; |
| 476 | +scanf("%s",ch); |
| 477 | +``` |
| 478 | + |
| 479 | +- 注意点: |
| 480 | + |
| 481 | +* 对一个字符串数组, 如果不做初始化赋值, 必须指定数组长度 |
| 482 | +* ch 最多存放由 9 个字符构成的字符串,其中最后一个字符的位置要留给字符串的结尾标示‘\0’ |
| 483 | +* 当用 scanf 函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符 |
| 484 | + |
| 485 | +### 字符串常用方法 |
| 486 | + |
| 487 | +- C 语言中供了丰富的字符串处理函数,大致可分为字符串的输入、输出、合并、修改、比较、转 换、复制、搜索几类。 |
| 488 | + |
| 489 | +* 使用这些函数可大大减轻编程的负担。 |
| 490 | +* 使用输入输出的字符串函数,在使用前应包含头文件"stdio.h" |
| 491 | +* 使用其它字符串函数则应包含头文件"string.h" |
| 492 | +- 字符串输出函数:puts |
| 493 | +- 格式: puts(字符数组名) |
| 494 | +- 功能:把字符数组中的字符串输出到显示器。即在屏幕上显示该字符串。 |
| 495 | +- 优点: |
| 496 | + |
| 497 | +* 自动换行 |
| 498 | +* 可以是数组的任意元素地址 |
| 499 | + |
| 500 | +- 缺点 |
| 501 | + |
| 502 | +* 不能自定义输出格式, 例如 puts("hello %i"); |
| 503 | + |
| 504 | +```c showLineNumbers |
| 505 | +char ch[] = "lnj"; |
| 506 | +puts(ch); //输出结果: lnj |
| 507 | +``` |
| 508 | +
|
| 509 | +> - puts 函数完全可以由 printf 函数取代。当需要按一定格式输出时,通常使用 printf 函数 |
| 510 | +- 字符串输入函数:gets |
| 511 | +- 格式: gets (字符数组名) |
| 512 | +- 功能:从标准输入设备键盘上输入一个字符串。 |
| 513 | +
|
| 514 | +```c showLineNumbers |
| 515 | +char ch[30]; |
| 516 | +gets(ch); // 输入:lnj |
| 517 | +puts(ch); // 输出:lnj |
| 518 | +``` |
| 519 | + |
| 520 | +> - 可以看出当输入的字符串中含有空格时,输出仍为全部字符串。说明 gets 函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与 scanf 函数不同的。 |
| 521 | +> - 注意 gets 很容易导致数组下标越界,是一个不安全的字符串操作函数 |
| 522 | +- 字符串长度 |
| 523 | +- 利用 sizeof 字符串长度 |
| 524 | + |
| 525 | +* 因为字符串在内存中是逐个字符存储的,一个字符占用一个字节,所以字符串的结束符长度也是占用的内存单元的字节数。 |
| 526 | + |
| 527 | +```c showLineNumbers |
| 528 | + char name[] = "it666"; |
| 529 | + int size = sizeof(name);// 包含\0 |
| 530 | + printf("size = %d\n", size); //输出结果:6 |
| 531 | +``` |
| 532 | +- 利用系统函数 |
| 533 | +
|
| 534 | +* 格式: strlen(字符数组名) |
| 535 | +* 功能:测字符串的实际长度(不含字符串结束标志‘\0’)并作为函数返回值。 |
| 536 | +
|
| 537 | +```c showLineNumbers |
| 538 | + char name[] = "it666"; |
| 539 | + size_t len = strlen(name2); |
| 540 | + printf("len = %lu\n", len); //输出结果:5 |
| 541 | +``` |
| 542 | +- 以“\0”为字符串结束条件进行统计 |
| 543 | + |
| 544 | +```c showLineNumbers |
| 545 | +/** |
| 546 | + * 自定义方法计算字符串的长度 |
| 547 | + * @param name 需要计算的字符串 |
| 548 | + * @return 不包含\0的长度 |
| 549 | + */ |
| 550 | +int myStrlen2(char str[]) |
| 551 | +{ |
| 552 | + // 1.定义变量保存字符串的长度 |
| 553 | + int length = 0; |
| 554 | + while (str[length] != '\0') |
| 555 | + { |
| 556 | + length++;//1 2 3 4 |
| 557 | + } |
| 558 | + return length; |
| 559 | +} |
| 560 | +/** |
| 561 | + * 自定义方法计算字符串的长度 |
| 562 | + * @param name 需要计算的字符串 |
| 563 | + * @param count 字符串的总长度 |
| 564 | + * @return 不包含\0的长度 |
| 565 | + */ |
| 566 | +int myStrlen(char str[], int count) |
| 567 | +{ |
| 568 | +// 1.定义变量保存字符串的长度 |
| 569 | + int length = 0; |
| 570 | +// 2.通过遍历取出字符串中的所有字符逐个比较 |
| 571 | + for (int i = 0; i < count; i++) { |
| 572 | +// 3.判断是否是字符串结尾 |
| 573 | + if (str[i] == '\0') { |
| 574 | + return length; |
| 575 | + } |
| 576 | + length++; |
| 577 | + } |
| 578 | + return length; |
| 579 | +} |
| 580 | +``` |
| 581 | +- 字符串连接函数:strcat |
| 582 | +- 格式: strcat(字符数组名 1,字符数组名 2) |
| 583 | +- 功能:把字符数组 2 中的字符串连接到字符数组 1 中字符串的后面,并删去字符串 1 后的串标志 “\0”。本函数返回值是字符数组 1 的首地址。 |
| 584 | +
|
| 585 | +```c showLineNumbers |
| 586 | +char oldStr[100] = "welcome to"; |
| 587 | +char newStr[20] = " lnj"; |
| 588 | +strcat(oldStr, newStr); |
| 589 | +puts(oldStr); //输出: welcome to lnj" |
| 590 | +``` |
| 591 | + |
| 592 | +> - 本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。要注意的是,字符数组 1 应定义足 够的长度,否则不能全部装入被连接的字符串。 |
| 593 | +- 字符串拷贝函数:strcpy |
| 594 | + `- 格式: strcpy(字符数组名1,字符数组名2) |
| 595 | +`- 功能:把字符数组 2 中的字符串拷贝到字符数组 1 中。串结束标志“\0”也一同拷贝。字符数名 2, 也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。 |
| 596 | + |
| 597 | +```c showLineNumbers |
| 598 | +char oldStr[100] = "welcome to"; |
| 599 | +char newStr[50] = " lnj"; |
| 600 | +strcpy(oldStr, newStr); |
| 601 | +puts(oldStr); // 输出结果: lnj // 原有数据会被覆盖 |
| 602 | +``` |
| 603 | +
|
| 604 | +> - 本函数要求字符数组 1 应有足够的长度,否则不能全部装入所拷贝的字符串。 |
| 605 | +- 字符串比较函数:strcmp |
| 606 | +- 格式: strcmp(字符数组名 1,字符数组名 2) |
| 607 | +- 功能:按照 ASCII 码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。 |
| 608 | +
|
| 609 | +* 字符串 1=字符串 2,返回值=0; |
| 610 | +* 字符串 1`>`字符串 2,返回值`>`0; |
| 611 | +* 字符串 1`<`字符串 2,返回值`<`0。 |
| 612 | +
|
| 613 | +```c showLineNumbers |
| 614 | + char oldStr[100] = "0"; |
| 615 | + char newStr[50] = "1"; |
| 616 | + printf("%d", strcmp(oldStr, newStr)); //输出结果:-1 |
| 617 | + char oldStr[100] = "1"; |
| 618 | + char newStr[50] = "1"; |
| 619 | + printf("%d", strcmp(oldStr, newStr)); //输出结果:0 |
| 620 | + char oldStr[100] = "1"; |
| 621 | + char newStr[50] = "0"; |
| 622 | + printf("%d", strcmp(oldStr, newStr)); //输出结果:1 |
| 623 | +``` |
| 624 | + |
| 625 | + |
| 626 | + |
| 627 | +## 结构体 |
| 628 | + |
| 629 | + |
| 630 | +## 联合体 |
0 commit comments