@@ -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- ```
0 commit comments