Skip to content

Commit 92dad59

Browse files
更新C语言文档结构
1 parent a6348c9 commit 92dad59

3 files changed

Lines changed: 455 additions & 383 deletions

File tree

docs/docs/选择编程语言/C/1变量.mdx

Lines changed: 0 additions & 382 deletions
Original file line numberDiff line numberDiff line change
@@ -313,385 +313,3 @@ int main(){
313313
return 0;
314314
}
315315
```
316-
317-
318-
319-
## putchar 和 getchar
320-
321-
向屏幕输出一个字符
322-
323-
```c showLineNumbers
324-
#include <stdio.h>
325-
int main(){
326-
char ch = 'a';
327-
putchar(ch); // 输出a
328-
}
329-
```
330-
331-
从键盘获得一个字符,
332-
333-
```c showLineNumbers
334-
#include <stdio.h>
335-
int main(){
336-
char ch;
337-
ch = getchar();// 获取一个字符
338-
printf("ch = %c\n", ch);
339-
}
340-
```
341-
342-
## printf
343-
344-
printf 函数称之为格式输出函数,方法名称的最后一个字母 f 表示 format。其功能是按照用户指定的格式,把指定的数据输出到屏幕上
345-
346-
printf 有两种基本用法:
347-
348-
1. 字符串字面量输出(非格式化输出)
349-
350-
当 printf 只输出**字符串字面量**且不包含任何**格式说明符**时,可以直接打印纯文本:
351-
352-
```c showLineNumbers
353-
#include <stdio.h>
354-
int main(){
355-
// 纯文本输出,不包含格式说明符
356-
printf("Hello, World!\n");
357-
printf("AaBb\n");
358-
printf("这是一行纯文本\n");
359-
return 0;
360-
}
361-
```
362-
363-
2. 格式化输出
364-
365-
调用格式为:`printf( 格式字符串, 待打印项1, 待打印项2,...);`
366-
367-
格式控制字符串形式: `%[标志][输出宽度][.精度][长度]类型`。类型是必选,其它是可选。
368-
369-
例如:
370-
```c showLineNumbers
371-
#include <stdio.h>
372-
int main(){
373-
int a = 10;
374-
int b = 20;
375-
// 最简单的形式,只使用类型。输出: 10 20
376-
printf("%d %d",a, b);
377-
378-
// 格式控制字符串和输出项在数量和类型上必须一一对应
379-
printf("%d %d %d",a, b); // 危险!输出项不足会导致未定义行为
380-
return 0;
381-
}
382-
```
383-
384-
### 类型
385-
386-
类型字符串用以表示输出数据的类型, 其格式符和意义如下所示
387-
388-
| 类型 | 含义 | 示例 |
389-
| --- | --- | --- |
390-
| **字符与字符串** | | |
391-
| **c** | 单个字符 | `%c` |
392-
| **s** | 字符串(char 数组) | `%s` |
393-
| **整数类型 (10进制)** | | |
394-
| **d / i** | 有符号 10 进制整数 | `%d`, `%i` |
395-
| **hd / hi** | short int(短整型) | `%hd`, `%hi` |
396-
| **ld / li** | long int(长整型) | `%ld`, `%li` |
397-
| **lld / lli** | **long long int(长长整型)** | `%lld`, `%lli` |
398-
| **u** | 无符号 10 进制整数 | `%u` |
399-
| **hu** | unsigned short int | `%hu` |
400-
| **lu** | unsigned long int | `%lu` |
401-
| **llu** | **unsigned long long int** | `%llu` |
402-
| **其他进制整数** | | |
403-
| **o** | 无符号 8 进制整数 | `%o` |
404-
| **lo / llo** | unsigned long / long long(8进制) | `%lo`, `%llo` |
405-
| **x / X** | 无符号 16 进制整数(`x`小写字母,`X`大写字母) | `%x`, `%X` |
406-
| **lx / lX** | unsigned long int(16进制) | `%lx`, `%lX` |
407-
| **llx / llX** | **unsigned long long int(16进制)** | `%llx`, `%llX` |
408-
| **浮点数类型** | | |
409-
| **f** | float / double(默认保留 6 位小数) | `%f` |
410-
| **lf** | double(printf中与%f通用,scanf中必须区分) | `%lf` |
411-
| **Lf** | long double(扩展精度浮点型) | `%Lf` |
412-
| **e / E** | 科学计数法(指数形式)输出浮点数 | `%e`, `%E` |
413-
| **Le / LE** | long double 的科学计数法形式 | `%Le`, `%LE` |
414-
| **g / G** | **自动选择**:根据数值大小自动选 `%f``%e/%E`(当指数 < -4 或 >= 精度时使用指数格式) | `%g`, `%G` |
415-
| **a / A** | **十六进制浮点数**,p记数法 (C99/C11标准) | `%a`, `%A` |
416-
| **特殊类型** | | |
417-
| **p** | 指针地址(十六进制形式) | `%p` |
418-
| **n** | 不产生输出,而是将**已打印字符数**存入对应的 int 指针变量 | `%n` |
419-
| **%** | 打印一个百分号字符 `%` 本身 | `%%` |
420-
421-
:::tip
422-
关于 `%i`:在 printf 中与 `%d` 相同;但在 scanf 中,`%i` 会根据输入的前缀自动识别进制(如 0x 开头识别为十六进制,0 开头识别为八进制)。
423-
:::
424-
425-
```c showLineNumbers
426-
#include <stdio.h>
427-
int main(){
428-
// 字符和字符串
429-
char ch = 'A';
430-
char str[] = "Hello";
431-
printf("字符: %c\n", ch); // A
432-
printf("字符串: %s\n", str); // Hello
433-
434-
// 各种整数类型
435-
short short_num = 12345;
436-
int int_num = 123456;
437-
long long_num = 1234567890L;
438-
long long longlong_num = 1234567890123456789LL;
439-
440-
// %提醒程序,要在该处打印一个变量,d表明把变量作为十进制整数打印。
441-
printf("short: %hd\n", short_num); // 12345
442-
printf("int: %d\n", int_num); // 123456
443-
printf("long: %ld\n", long_num); // 1234567890
444-
printf("long long: %lld\n", longlong_num); // 1234567890123456789
445-
446-
// 无符号整数
447-
unsigned int uint_num = 4294967295U;
448-
unsigned long long ulonglong_num = 18446744073709551615ULL;
449-
450-
printf("unsigned int: %u\n", uint_num); // 4294967295
451-
printf("unsigned long long: %llu\n", ulonglong_num); // 18446744073709551615
452-
453-
// 不同进制输出
454-
int num = 255;
455-
printf("十进制: %d\n", num); // 255
456-
printf("八进制: %o\n", num); // 377
457-
printf("十六进制: %x\n", num); // ff
458-
printf("十六进制(大写): %X\n", num); // FF
459-
460-
// long long 的不同进制
461-
long long big_num = 255LL;
462-
printf("long long 八进制: %llo\n", big_num); // 377
463-
printf("long long 十六进制: %llx\n", big_num); // ff
464-
465-
// 浮点数
466-
float f_num = 3.14159f;
467-
double d_num = 3.141592653589793;
468-
469-
printf("float: %f\n", f_num); // 3.141590
470-
printf("double: %lf\n", d_num); // 3.141593
471-
printf("科学计数法: %e\n", d_num); // 3.141593e+00
472-
printf("自动格式: %g\n", d_num); // 3.14159
473-
474-
// 指针地址
475-
int *ptr = &int_num;
476-
printf("指针地址: %p\n", ptr); // 类似 0x7fff5fbff6ac
477-
478-
return 0;
479-
}
480-
```
481-
482-
:::tip 打印%符号
483-
484-
由于printf()函数使用%符号来标识转换说明,因此打印%符号就成了个问题。
485-
486-
如果单独使用一个%符号,编译器会认为漏掉了一个转换字符。解决方法很简单,使用两个%符号就行了。
487-
488-
`printf("%d%% 的人是男性.\n", 50);` 50%的人是男性
489-
:::
490-
491-
492-
### 标志、宽度、精度、长度
493-
494-
在 C 语言中,`printf` 的完整格式化语法为: `printf("a = %[标志][宽度][.精度][长度转换修饰符]类型", a);`
495-
496-
#### 格式标志符(Flags)
497-
498-
| 标志 | 含义 | 示例 |
499-
| --- | --- | --- |
500-
| **`-`** | **左对齐**。默认是右对齐。 | `%-5d` |
501-
| **`+`** | **显示正负号**。正数前加 `+`,负数前加 `-`| `%+d` |
502-
| **`0`** | **零填充**。右对齐时,空位用 `0` 填充而非空格。 | `%05d` |
503-
| **`空格`** | **留空正号**。正数前加空格,负数前显示 `-`| `% d` |
504-
| **`#`** | **特殊前缀**。对 `o``0`;对 `x/X``0x/0X`;对浮点数强制显示小数点。 | `%#x` |
505-
506-
#### 宽度与精度控制
507-
508-
* **宽度 (Width)**:用十进制整数指定最小输出位数。
509-
* 实际位数 < 宽度:用空格(或 0)补位。
510-
* 实际位数 > 宽度:按实际位数原样输出。
511-
512-
513-
* **精度 (.Precision)**:以 `.` 开头,后跟整数。
514-
* **浮点数**:控制小数点后的位数(四舍五入)。
515-
* **字符串**:控制最大输出字符数。
516-
已经为你将**长度转换修饰符(Length Modifiers)**加入到体系中。
517-
518-
#### 长度转换修饰符
519-
520-
| 长度插件 | 对应数据类型 | 说明 |
521-
| --- | --- | --- |
522-
| **`hh`** | `char` / `unsigned char` | 以单字节整数形式输出 (C99) |
523-
| **`h`** | `short` / `unsigned short` | 短整型 |
524-
| **(无)** | `int` / `unsigned int` / `float` | 默认整型/单精度浮点型 |
525-
| **`l`** (小写L) | `long` / `unsigned long` / `double` | 长整型或双精度浮点 |
526-
| **`ll`** (双L) | `long long` / `unsigned long long` | **长长整型** (C99) |
527-
| **`L`** (大写L) | `long double` | 扩展精度浮点型 |
528-
| **`z`** | `size_t` | 用于输出 `sizeof` 的返回结果 (C99) |
529-
530-
531-
如果你想打印一个:**左对齐、占10位宽、保留2位小数、双精度**的数字:
532-
`%-10.2lf`
533-
534-
```c showLineNumbers
535-
#include <stdio.h>
536-
537-
int main() {
538-
double d = 123.456;
539-
540-
// [标志:-][宽度:10][精度:.2][长度:l][类型:f]
541-
printf("结果: |%-10.2lf|\n", d);
542-
// 输出: |123.46 | (左对齐,总宽10,四舍五入)
543-
544-
// [标志:0][宽度:10][精度:.2][长度:l][类型:f]
545-
printf("结果: |%010.2lf|\n", d);
546-
// 输出: |0000123.46| (右对齐,0填充)
547-
548-
return 0;
549-
}
550-
551-
```
552-
553-
554-
## scanf
555-
556-
scanf 函数用于接收键盘输入的内容, 是一个阻塞式函数,程序会停在 scanf 函数出现的地方。直到用户输入数据,按下回车键(输入`\n`)后,scanf接收到数据才会执行后面的代码。
557-
558-
调用格式为:`scanf("格式控制字符串", 地址列表);`
559-
560-
地址列表项中只能传入变量地址, 变量地址可以通过&符号+变量名称的形式获取
561-
562-
```c showLineNumbers
563-
#include <stdio.h>
564-
int main(){
565-
int number;
566-
scanf("%d", &number); // 接收一个整数
567-
printf("number = %d\n", number);
568-
}
569-
```
570-
571-
它在遇到第1个空白(空格、制表符或换行符)时就不再读取输入。
572-
573-
```c showLineNumbers
574-
/* praise1.c -- 使用不同类型的字符串 */
575-
#include <stdio.h>
576-
int main(void)
577-
{
578-
char name[40];
579-
printf("What's your name? ");
580-
scanf("%s", name);
581-
printf("Hello, %s.\n", name);
582-
return 0;
583-
}
584-
585-
//What's your name? Angela Plains
586-
//Hello, Angela.
587-
```
588-
589-
### 分隔符
590-
591-
如果你要输入多个数据,怎么确定输入的哪个数据是给哪个变量赋值?这就是分隔符的作用。
592-
593-
```c showLineNumbers
594-
#include <stdio.h>
595-
int main(){
596-
int number;
597-
int value;
598-
// 推荐使用空格
599-
// 可以输入 数字 空格 数字
600-
scanf("%d %d", &number, &value);
601-
printf("number = %d\n", number);
602-
printf("value = %d\n", value);
603-
}
604-
```
605-
606-
如果将分隔符指定为其他形式,例如逗号需要<Highlight>注意中英文之分</Highlight>,再次推荐使用空格。
607-
608-
```c showLineNumbers
609-
#include <stdio.h>
610-
int main(){
611-
int number;
612-
int value;
613-
// 输入 数字,数字 即可
614-
scanf("%d,%d", &number, &value);
615-
printf("number = %d\n", number);
616-
printf("value = %d\n", value);
617-
}
618-
```
619-
620-
下面的写法相当于把分割符指定为`number = `
621-
622-
```c showLineNumbers
623-
#include <stdio.h>
624-
int main(){
625-
int number;
626-
// 用户必须输入number = 数字 , 否则会得到一个意外的值
627-
// 示例:如果你希望输入10,就必须输入number = 10【回车】
628-
scanf("number = %d", &number);
629-
printf("number = %d\n", number);
630-
}
631-
```
632-
633-
### 忽略空白字符
634-
635-
接收非字符和字符串类型时, 空格、Tab 和回车会被自动忽略
636-
637-
```c showLineNumbers
638-
#include <stdio.h>
639-
int main(){
640-
float num;
641-
// 例如:输入 Tab 空格 回车 回车 Tab 空格 3.14 , 得到的结果还是3.14
642-
scanf("%f", &num);
643-
printf("num = %f\n", num);
644-
}
645-
```
646-
647-
### 缓冲区
648-
649-
- 系统会将用户输入的内容先放入输入缓冲区
650-
- scanf 方式会从输入缓冲区中逐个取出内容赋值给变量
651-
- 如果输入缓冲区的内容不为空,scanf 会一直从缓冲区中获取,而不要求再次输入
652-
653-
```c showLineNumbers
654-
#include <stdio.h>
655-
int main(){
656-
int num1;
657-
int num2;
658-
char ch1;
659-
// 如果在这里一次性输入:10a20b30
660-
// 从缓冲区中提取整数、文本、整数
661-
scanf("%d%c%d", &num1, &ch1, &num2);
662-
printf("num1 = %d, ch1 = %c, num2 = %d\n", num1, ch1, num2);
663-
char ch2;
664-
int num3;
665-
// 继续从缓冲区中提取文本、整数(无需输入)
666-
scanf("%c%d",&ch2, &num3);
667-
printf("ch2 = %c, num3 = %d\n", ch2, num3);
668-
//
669-
}
670-
```
671-
672-
那我万一输入多了,影响后面的变量接收怎么办?
673-
674-
可以利用以下方法清空输入缓冲区:
675-
676-
```c showLineNumbers
677-
#include <stdio.h>
678-
int main(){
679-
int num1;
680-
int num2;
681-
char ch1;
682-
scanf("%d%c%d", &num1, &ch1, &num2);
683-
printf("num1 = %d, ch1 = %c, num2 = %d\n", num1, ch1, num2);
684-
685-
// 标准方法,通过getchar获取到回车符或EOF为止。
686-
int c;
687-
while ((c = getchar()) != '\n' && c != EOF);
688-
689-
// 方法二
690-
setbuf(stdin, NULL);
691-
692-
char ch2;
693-
int num3;
694-
scanf("%c%d",&ch2, &num3);
695-
printf("ch2 = %c, num3 = %d\n", ch2, num3);
696-
}
697-
```

docs/docs/选择编程语言/C/2数据.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
sidebar_position: 2
3-
title: 基本类型
3+
title: 数据
44
---
55

66
C语言基本数据类型:`char``int``float``double``void`(不能被修饰)、`_Bool`(不能被修饰)、`_Complex`(可指定单精度或双精度)和`_Imaginary`(可指定单精度或双精度)

0 commit comments

Comments
 (0)