【C语言学习笔记】输出函数puts()
输出函数 puts()
头文件
stdio.h
函数原型
int puts(const char *string);
功能
向控制台输出一串字符串
即送一字符串到stdout中
参数
输入:字符串指针
输入可以是字符串数组,也可以是字符串常量
思考:
puts()函数的输入是一个字符串指针。当使用一个字符串数组名作为输入时,数组名此时表示一个指向数组的指针值,这符合puts()的输入要求,并能够正确输出。但是,当输入为一个字符串常量时,函数仍然能够正常的输出字符串。
可以作如下猜测:
1.字符串常量的取值实际上是一个地址值,即指针,这样才能够满足puts()函数对输入参数的要求,而这个指针应该指向了字符串常量实际所在的地址。
2.程序运行时,字符串常量将占用内存空间,这样才能保证puts()函数能通过指针找到要输出的数据。
既然字符串常量占用内存,那么应该就能够得到它的地址并输出。
输出:成功标志
函数的返回值为一个整形数据,标志函数执行是否成功。若字符串成功输出,则返回值为非负数(通常为0);若字符串输出失败,则返回值为EOF(通常为-1)。
特性
puts()和printf()都能够用来输出字符串,但是两者有些许不同。puts()在输出字符串后,会自动换行,而printf不会自动换行。两者有如下关系:
puts(s)↔printf(“%s\n”,s);
puts()函数仍然以’\0’来确定字符串的结尾。
- 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()相关推荐
- C语言学习笔记09-数组、字符数组、字符串数组、二维数组(单字符输入输出putchar、getchar,字符串输入输出的scanf、gets、puts)
C语言数组 数组作用:可以用来保存很多记录(可以看成一种大容器).一些简单游戏也基本由数组实现,如游戏地图(二维数组)等等. 一个数组 划分 多个单元(下标区分) -存放-> 多个同类元 ...
- 史上最全C语言学习笔记
最全C语言学习笔记 学习目标 学习编程最主要目标 分析问题的能力.构造算法的能力.编程的能力. 调试程序的能力. 学习方法手段 如何操作? 解题思路:重点要放在解题的思路上 一开始就要学会看懂程序,编 ...
- C语言学习笔记10-指针(动态内存分配malloc/calloc、realloc、释放free,可变数组实现;Tips:返回指针的函数使用本地变量有风险!;最后:函数指针)
C语言:指针 1. 指针:保存地址的变量 *p (pointer) ,这种变量的值是内存的地址. 取地址符& 只用于获取变量(有地址的东西)的地址:scanf函数-取地址符 地址的大小 ...
- C语言如何加缓冲,C语言学习笔记之输出缓冲
在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...
- 梓益C语言学习笔记之链表&动态内存&文件
梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...
- 6.方法(go语言学习笔记)
6.方法(go语言学习笔记) 目录 定义 匿名字段 方法集 表达式 1. 定义 方法是与对象实例绑定的特殊函数. 方法是面向对象编程的基本概念,用于维护和展示对象的自身状态.对象是内敛的,每个实例对象 ...
- 梓益C语言学习笔记之指针
梓益C语言学习笔记之指针 一.32位平台下,地址是32位,所以指针变量占32位,共4个字节 二.内存单元的地址即为指针,存放指针的变量称为指针变量,故:"指针"是指地址,是常量,& ...
- c语言中void arrout,c语言学习笔记(数组、函数
<c语言学习笔记(数组.函数>由会员分享,可在线阅读,更多相关<c语言学习笔记(数组.函数(53页珍藏版)>请在人人文库网上搜索. 1.数组2010-3-29 22:40一维数 ...
- c语言float二进制输出代码_C语言学习笔记——学前知识概述
将我大一学习C语言时做的笔记拿来与大家分享,内容比较浅显,比较适合初学者,如有错误还请见谅,提出改正,谢谢! 前言:此C语言笔记是本人在自学时记录的一些重点或初学者常犯的错误,希望我的这本笔记能够对大 ...
- c语言学习笔记【结构体02】结构体指针变量与结构体变量的函数参数,C语言学习笔记结构体02结构体指针变量与结构体变量的函数参数.docx...
C 语言学习笔记[结构体02]结构体指针变量与结构体变量 的函数参数 C 语言学习笔记之结构体指针变量一提指针,那可 是 C 语言的核心了,有多少学子曾拜倒在指针的脚下.单纯的说指针,其实并不难,但是 ...
最新文章
- const constptr 和引用的盲点(未解决)
- md是什么类型的文件?怎么打开md文件,Markdown的编写,Markdown转化为html
- 模板:Prufer序列
- Semantic Web 文章目录
- 详解nullable、firstpos、lastpos和followpos的计算规则
- linux sleeping进程多_一文掌握Linux实战技能系统管理篇
- mysql 语句优化的几种方式(总结)
- 自用plsql破解方法
- MySQL图书馆借书管理系统试题
- 奇迹mu开服教程:服务端的架设及开服注意事项
- NOIP总结与反思及对今后的期望
- 人民搜索2013年招聘的三道算法题 西安站
- 点积与向量积(点乘与叉乘)
- 两年3亿用户,淘特跑出中国电商“加速度”
- ATTck 命令执行 —— 远程动态数据交换
- java.net.url 兼容_java.net.Url类的应用(网络编程)
- 净亏10.89亿欧元!法雷奥:2021年仍需保持谨慎,ADAS业务表现最佳
- 主板2个M. 2接口,哪个m2插槽是与CPU直连?总结不得不说PCIE知识
- dlg.DoModal()介绍
- mysql 授予权限语句,授予MySQL用户权限的语句