输出函数 puts()

头文件

stdio.h

函数原型

int puts(const char *string);

功能

向控制台输出一串字符串

即送一字符串到stdout中

参数

输入:字符串指针

输入可以是字符串数组,也可以是字符串常量

思考:
puts()函数的输入是一个字符串指针。当使用一个字符串数组名作为输入时,数组名此时表示一个指向数组的指针值,这符合puts()的输入要求,并能够正确输出。但是,当输入为一个字符串常量时,函数仍然能够正常的输出字符串。
可以作如下猜测:
1.字符串常量的取值实际上是一个地址值,即指针,这样才能够满足puts()函数对输入参数的要求,而这个指针应该指向了字符串常量实际所在的地址。
2.程序运行时,字符串常量将占用内存空间,这样才能保证puts()函数能通过指针找到要输出的数据。
既然字符串常量占用内存,那么应该就能够得到它的地址并输出。

输出:成功标志

函数的返回值为一个整形数据,标志函数执行是否成功。若字符串成功输出,则返回值为非负数(通常为0);若字符串输出失败,则返回值为EOF(通常为-1)。

特性

  1. puts()和printf()都能够用来输出字符串,但是两者有些许不同。puts()在输出字符串后,会自动换行,而printf不会自动换行。两者有如下关系:

    puts(s)↔printf(“%s\n”,s);

  2. puts()函数仍然以’\0’来确定字符串的结尾。

  3. puts()函数只能够输出字符串,参数只能是字符指针。输入若为其他类型数据或指针,编译器报错,无法进行数据类型转换。

实验

这里使用的实验平台为VS2013,不排除在其他平台上会有出现不同实验结果的可能

字符串常量占用内存空间

前面说到,字符串常量在内存中将占用空间,并且能够取得它的地址并输出。下面用实验进行简单的证明。

#include <stdio.h>
int main()
{char *p;p = "Hello World!";printf("%p\n%s\n", "Hello World!", "Hello World!");printf("%p\n%s\n", p, p);return 0;
}

输出如下

012A5858
Hello World!
012A5858
Hello World!
请按任意键继续. . .

可见字符串本身的取值就是一个指针,而字符串的数据则保存在指针所指向的内存空间。
另外可以发现,对于完全相同的字符串常量,在内存中只会记录一次,而不会重复占用空间。

puts()与printf()

二者最直观的区别就是,是否会自动换行。

#include <stdio.h>
int main()
{puts("Hello.");printf("Hello.\n" );printf("Hello.");return 0;
}

输出如下

Hello.
Hello.
Hello.请按任意键继续. . .

前两种输出方式的输出结果完全相同,第三种输出,printf中没有写入换行符,最后输出并没有换行。
可以看出,puts函数在输出时,会自动换行,而printf不会。

字符串长度由’\0’确定

puts输出字符串,从输入指针所指向的字符开始,到遇到的第一个’\0’字符结束。

#include <stdio.h>
int main()
{char c[10] = "abcde\0fgh";int i;puts(c);for (i = 0; i < 10; i++){putchar(c[i]);}putchar('\n');return 0;
}

输出如下

abcde
abcde fgh
请按任意键继续. . .

可以看到,虽然’\0’以后的字符确实在数组中存在,但是puts并没有对这些字符进行输出。
因此,puts函数输出字符串是以’\0’作为结束标记的。
另外可以看到,在对字符串数组初始化时,数组并没有在’\0’字符处就停止了拷贝,而是将字符串所有的字符全部拷贝进了数组。因此可以了解到,并不是所有对字符串的操作都是以’\0’字符作为结束标记的。
对此思考了一个问题,利用字符串对字符串数组进行初始化时,字符串是以怎样的数据类型进行解析的。

#include <stdio.h>
int main()
{char a[10] = "abcde";char *p = a;char b[10] = p;     //e1char c= "abcde";    //e2char d[10] = a;     //e3char e[10] = (const char[10])a; //e4return 0;
}

编译出错,错误提示如下

e1:error C2440: “初始化”: 无法从“char *”转换为“char [10]”
e2:error C2440: “初始化”: 无法从“const char [6]”转换为“char”
e3:error C2075: “d”: 数组初始化需要大括号
e4:error C2440: “类型转换”: 无法从“char [10]”转换为“const char [10]”

从第一个错误信息可以了解到,字符指针不能用来初始化字符数组,也就是说字符串的数据类型并不是字符指针。
那字符串的数据类型到底是什么呢。于是看第二个错误信息。在这里故意将字符串赋值给一个字符变量,这自然是非法的,从而可以让编译器告诉我们,我们在将什么数据类型赋值给字符变量。
从第二个错误信息中,我们就可以了解到,编译器将字符串解析为了字符数组常量,也证实了之前字符串不是指针的推断(指针与数组并不是同一种类型,它们在行为上有些类似,但是实质并不相同)。这也解释了为什么在初始化时,程序能够知道字符串的长度,因为数组类型不同于单纯的指针,它是有长度信息的。
既然初始化用的是常量字符数组,那字符数组变量能用于初始化吗。于是有了错误3和错误4。
错误3告诉我们,字符数组变量不能为字符数组初始化。
错误4告诉我们,尝试将字符数组变量类型转换为字符数组常量是非法的行为。

从上面的分析可以知道,在目前为止本人所知道的数据类型中,不考虑常规的大括号初始化方式,能直接为字符数组初始化的数据类型,就只有字符串,即字符数组常量。

【C语言学习笔记】输出函数puts()相关推荐

  1. C语言学习笔记09-数组、字符数组、字符串数组、二维数组(单字符输入输出putchar、getchar,字符串输入输出的scanf、gets、puts)

    C语言数组   数组作用:可以用来保存很多记录(可以看成一种大容器).一些简单游戏也基本由数组实现,如游戏地图(二维数组)等等.   一个数组 划分 多个单元(下标区分) -存放-> 多个同类元 ...

  2. 史上最全C语言学习笔记

    最全C语言学习笔记 学习目标 学习编程最主要目标 分析问题的能力.构造算法的能力.编程的能力. 调试程序的能力. 学习方法手段 如何操作? 解题思路:重点要放在解题的思路上 一开始就要学会看懂程序,编 ...

  3. C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)

    C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址.   取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符   地址的大小 ...

  4. C语言如何加缓冲,C语言学习笔记之输出缓冲

    在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...

  5. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

  6. 6.方法(go语言学习笔记)

    6.方法(go语言学习笔记) 目录 定义 匿名字段 方法集 表达式 1. 定义 方法是与对象实例绑定的特殊函数. 方法是面向对象编程的基本概念,用于维护和展示对象的自身状态.对象是内敛的,每个实例对象 ...

  7. 梓益C语言学习笔记之指针

    梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...

  8. c语言中void arrout,c语言学习笔记(数组、函数

    <c语言学习笔记(数组.函数>由会员分享,可在线阅读,更多相关<c语言学习笔记(数组.函数(53页珍藏版)>请在人人文库网上搜索. 1.数组2010-3-29 22:40一维数 ...

  9. c语言float二进制输出代码_C语言学习笔记——学前知识概述

    将我大一学习C语言时做的笔记拿来与大家分享,内容比较浅显,比较适合初学者,如有错误还请见谅,提出改正,谢谢! 前言:此C语言笔记是本人在自学时记录的一些重点或初学者常犯的错误,希望我的这本笔记能够对大 ...

  10. c语言学习笔记【结构体02】结构体指针变量与结构体变量的函数参数,C语言学习笔记结构体02结构体指针变量与结构体变量的函数参数.docx...

    C 语言学习笔记[结构体02]结构体指针变量与结构体变量 的函数参数 C 语言学习笔记之结构体指针变量一提指针,那可 是 C 语言的核心了,有多少学子曾拜倒在指针的脚下.单纯的说指针,其实并不难,但是 ...

最新文章

  1. const constptr 和引用的盲点(未解决)
  2. md是什么类型的文件?怎么打开md文件,Markdown的编写,Markdown转化为html
  3. 模板:Prufer序列
  4. Semantic Web 文章目录
  5. 详解nullable、firstpos、lastpos和followpos的计算规则
  6. linux sleeping进程多_一文掌握Linux实战技能系统管理篇
  7. mysql 语句优化的几种方式(总结)
  8. 自用plsql破解方法
  9. MySQL图书馆借书管理系统试题
  10. 奇迹mu开服教程:服务端的架设及开服注意事项
  11. NOIP总结与反思及对今后的期望
  12. 人民搜索2013年招聘的三道算法题 西安站
  13. 点积与向量积(点乘与叉乘)
  14. 两年3亿用户,淘特跑出中国电商“加速度”
  15. ATTck 命令执行 —— 远程动态数据交换
  16. java.net.url 兼容_java.net.Url类的应用(网络编程)
  17. 净亏10.89亿欧元!法雷奥:2021年仍需保持谨慎,ADAS业务表现最佳
  18. 主板2个M. 2接口,哪个m2插槽是与CPU直连?总结不得不说PCIE知识
  19. dlg.DoModal()介绍
  20. mysql 授予权限语句,授予MySQL用户权限的语句

热门文章

  1. 漫谈程序员系列 薪资 你是我不能言说的伤
  2. 漫谈敏捷方法中的信任
  3. 一个直肠癌患者的最后50天,转发自阮一峰博客
  4. html怎样把两张图片重叠6,两张照片重叠成一张-如何将两张相片重叠放在一起?...
  5. 数列和级数(基本概念)
  6. 交换机VLANIF配置
  7. Yolov5学习笔记(1)——训练出自己的模型
  8. 水仙花数徐静春c语言,今日冬至|不疾不徐,静候春来!
  9. 加法的横式竖式教案c语言,竖式进位加法教案
  10. [渝粤教育] 中国地质大学 计算机会计理论与实务 复习题