C语言第三天
字符串和格式化输入
由于C语言没有String类型的表示,因此字符串只可以是char类型的数组形式表达。
小试牛刀
#include<stdio.h>
#include<string.h>
#define MAXNUM 64
int main(void){
float weight,volumn;
char name[40];
printf("Please input your name:");
scanf("%s",name);
int size=sizeof(name);
printf("Your name is %d Byte \n",size);
int letters = strlen(name);
printf("Your name is %d letters. \n",letters);
scanf("%f",&weight);
volumn=weight/MAXNUM;
printf("Your weight/MAXNUM is %.2f",volumn);
}
- 未知函数解释
函数 | 解释 |
---|---|
strlen() | 获取字符串长度 |
#define MAXNUM 64 | 用于定义字符常量 |
- 遗留问题
大家看代码时会注意到name前没有&而weight前有&,这是为什么?两者又有什么区别呢?大家接着往下看便会了解。
字符串
- 简介
前边已说过C语言没有专门用于存储字符串的变量类型,但char的数组形式可以存储字符串,数组是由连续的存储单元组成。在上述程序中:char name[40],由于C语言在char数组中需要字符\0标记字符串结束,因此字符\0占用一个存储单元。这里大家就可以得出结论,C语言的char类型数组可以存储39(按照上边程序解释)个字符,剩下一个留给空字符(\0)。
注意:空字符\0,计算机会自行处理,大家在编写代码时不要自行添加。 - 小例
#include<stdio.h>
#define STRING_TEST "You are very good."
int main(void){
char name[40];
printf("Please input your name:");
scanf("%s",name);
printf("Ha %s.%s",name,STRING_TEST);
}
看输出结果大家会感到奇怪,为什么name 只是输出了Gao,后边的Shanwei怎么没有输出来了?这里给大家解释一下:scanf()函数在读取输入字符串name时不能有空格,当遇到空格时便会停止读取。但大家也不要着急,C语言还提供了另一种函数fgets(),用于读取一般字符串。
- fgets()函数应用
#include<stdio.h>
int main(void){
char name[40];
printf("Please input your name:");
fgets(name,12,stdin);
printf("My name is %s",name);
}
上边便是fgets()简单例子。但是fgets()的应用大家可能不是很理解,它里边的参数怎么解释,下边继续给大家分析该函数参数参数的应用:
fgets(char * s, int n,FILE *stream)各参数的解释说明:
参数 | 解释说明 |
---|---|
s | 指向的是输入的数据 |
n | 从流中读入的数据,也就是读取字符串的长度,记住这里包括空字符(\0) |
stream | 指向读取的流意思是从何种流读取数据 |
stream流的介绍:
流 | 解释说明 |
---|---|
stdin | 标准输入流,也就是缓冲区当键盘输入数据时,数据暂存在缓冲区中,获取数据直接从缓冲区中获取。 |
文件流 | 将数据存储到文件中,读取数据从文件中读取。 |
- “g”与‘g’的区别
看到上边大家可能会觉得这不是一样吗?博主提出这个问题是不是脑子被驴踢了,这个是不可能的!“g”是字符串常量,‘g’是字符常量两者在数据类型有所区别,‘g’是char类型,“g”是char数组类型。“g”是由两个字符组成,而‘g’是由一个字符组成。下边我们用图来说话:
- strlen()函数
和sizeof()函数类似,但也有一定的区别,sizeof()函数是返回的是给定对象所占的字节多少,而strlen()返回的是给定字符串的大小。由于char类型占用一个字节,因此在sizeof()和strlen()函数在一定的基础上可以看做一样,但有一点依然不同:sizeof()是指整个字符串数组申请的空间大小尽管字符串为空,strlen()函数是指字符串中存在的数据长度,是两函数的主要区别点。依然用实例说话,请大家看下边的代码:
#include<stdio.h>
#include<string.h>
int main(void){
char name[40];
printf("Please input your name:");
scanf("%s",name);
int num_Byte=sizeof(name);
int num_Len=strlen(name);
printf("Byte is %d,Length is %d.",num_Byte,num_Len);
}
常量
定义常量有两种方式:
- int NUM=120; : 这种方法虽然定义了常量,但操作失误容易修改常量值。
- #define NUM 20 :这种方法定义常量比较好一些,以后也请大家用该种方法。使用该方法需要注意常量名和常量值之间不能添加任何东西。例如:#define NUM=20 这种常量定义方法定义成NUM的值为=20。
const限定符
上述博主提到了int NUM=120 定义常量的方法,博主不建议使用该方法,但是C语言就喜欢做打脸的活计。大家请看const限定符的出现改变了这一情况。const限定一个变量成为可读,不可修改。
使用例子如下:const int NUM =10;
C语言自带常量库
当然,C语言也会定义一些自己的常量,也叫作明示常量,有哪些明示常量这里不在详述,大家百度一下便一目了然。
printf()函数详解
printf()函数的使用相信大家都已经了解,但是打印数据所用的符号(转换说明)需要大家了解,在不同的需求中需要不同的转换说明。想要了解转换说明的读者,可自行百度了解,这里不在详细讲述。
转换说明修饰符(%和转换说明之间)
在输出数据时,大家可能都会遇到一些对输出数据的需求,例如对于浮点数只想输出小数点的后两位时只需%.2f,这里.2便是修饰符。如下几张图引用C Primer Plus第六版:
- 类型可移植
sizeof()函数,sizeof()函数返回值是参数所占用字节的大小,该值为无符号整数。因此在输出该函数返回值所需的转换说明有%u、%lu、%llu,又因为不同的系统所需的转换说明不同,在移植上就会出现一定的问题。- stddef.h头文件把size_t定义成系统使用sizeof返回的类型。
- 使用转换说明修饰符z,表示打印相应的类型。
- float参数的转换
在C语言中大家都会发现double和float的转换说明是一样的,这是为何?这里博主给大家解释一下:在C语言中是没有float的转换说明,printf()函数在输出float类型值时会将float自动转换为double类型。
转换说明标记
修饰符和标记使用示例
#include<stdio.h>
#define INT_TEST_NUM 666
#define STRING_TEST_CHAR "I am a postgradute"
int main(void){
/*
标记 -,+
修饰符 数字(最小字段宽度)
*/
printf("!%d! \n",INT_TEST_NUM);
printf("!%2d! \n",INT_TEST_NUM);
printf("!%10d! \n",INT_TEST_NUM);
printf("!%-10d! \n",INT_TEST_NUM);
printf("!%-+10d! \n",INT_TEST_NUM);
printf("!%+d! \n",INT_TEST_NUM);
/*
浮点型修饰符 e、.数字
标记 0
*/
printf("--------Float----------\n");
const float FLOAT_TEST_NUM=6666.666;
printf("!%f! \n",FLOAT_TEST_NUM);
printf("!%e! \n",FLOAT_TEST_NUM);
printf("!%4.2f! \n",FLOAT_TEST_NUM);
printf("!%3.1f! \n",FLOAT_TEST_NUM);
printf("!%4.3E! \n",FLOAT_TEST_NUM);
printf("!%+4.4f! \n",FLOAT_TEST_NUM);
printf("!%08.3f! \n",FLOAT_TEST_NUM);
//0标记打印值前以0填充 10表示数值宽度 .3表示小数点后的数字长度
printf("!%010.3f! \n",FLOAT_TEST_NUM);
printf("--------char[40]---------\n");
printf("!%s!\n",STRING_TEST_CHAR);
printf("!%2s! \n",STRING_TEST_CHAR);
printf("!%4s!\n",STRING_TEST_CHAR);
printf("!%22s!\n",STRING_TEST_CHAR);
//.5表示限制打印字符个数,该表示printf()表示输出5个字符
printf("!%22.5s!\n",STRING_TEST_CHAR);
printf("!%-22.5s!\n",STRING_TEST_CHAR);
}
转换说明的注意示例
#include<stdio.h>
int main(void){
float f_test_1=3.0;
double d_test_1=3.0;
long int li_test_1=200000000;
long int li_test_2=645230556;
printf("%e %e %e %e \n",f_test_1,d_test_1,li_test_1,li_test_2);
printf("%ld %ld \n",li_test_2,li_test_1);
printf("%f %f %f %f \n",f_test_1,d_test_1,li_test_1,li_test_2);
}
大家会看到第一行输出,输出整数时与预想结果不同,这里解释如下:由于double所占字节为8个字节,而long int依然占四个字节,在long int转换为double类型时所需li_test_1四个字节和其相邻的四个字节。
printf()返回值
大家所用的输出函数,也是有返回值的,那么它的返回值是什么,有什么作用呢?printf()函数返回值是打印字符的个数,但如果输出错误会返回负数,这一作用具有检查输出错误非常有用。下图依然是代码示例:
#include<stdio.h>
#define STRING_NAME "I am name is GaoShanWei!"
int main(void){
int printf_num=printf("%s\n",STRING_NAME);
printf("%d",printf_num);
}
- 打印较长字符串处理方法
有时大家会遇到输出字符串输出太长的情况,如果不加处理可能就会在一行中输出所有的字符,这样观看起来也是十分不方便,面对这种情况前辈们举出如下几种方法:
1. 将一段很长的字符串分割处理,分批输出。
2. 利用+enter键实现
3. 利用““””来实现。
代码示例如下:
#include<stdio.h>
int main(void){
/*
如下该段字符,我们查看起来不是很直观,还得移动鼠标
*/
printf("Man's youth is a wonderful thing:it is so full of anguish and of magic and he never comes to know it as it is.");
printf("\n -------------------------------------\n");
/*
如下是第一种方法,将其分割成一小句,通过多次使用printf()函数实现输出。
*/
printf("Man's youth is a wonderful thing:");
printf("it is so full of anguish and of ");
printf("magic and he never comes to know ");
printf("it as it is.");
printf("\n -------------------------------------\n");
/*
如下是第二种思想,只需调用一次printf()函数。不要怀疑此处缩进有问题,
大家可以尝试按正常缩进运行一下便会发现有什么问题了!
*/
printf("Man's youth is a wonderful thing:\
it is so full of anguish and of\
magic and he never comes to know\
it as it is.");
printf("\n -------------------------------------\n");
/*
如下为第三种思想,只需调用一次printf()函数。
*/
printf("Man's youth is a wonderful thing:"
"it is so full of anguish and of"
" magic and he never comes to know"
" it as it is.");
}
scanf()函数
输入函数有很多个,但是scanf()函数确是最通用的一个,它可以输入不同格式的数据。scanf()有一个作用是将从键盘中输入的文本数据(字符串)转换为相应的所需类型。
注意:
1. scanf()函数读取基本数据类型时,需要变量名前加&。
2. scanf()函数读取字符串类型时,不需要变量名前加&。
3. scanf()函数使用的参数是指向变量的指针,不能使用常量和表达式。
- 转换说明
- 修饰符
scanf()函数小注意
在使用scanf()函数时大家可能会遇到这种情况:scanf()函数中多个转换说明的使用,依然靠例子说话,明人不说暗话!
#include<stdio.h>
int main(void){
int num1,num2,num3;
//第一种
scanf("%d %d %d",&num1,&num2,&num3);
printf("%d %d %d \n",num1,num2,num3);
printf("------------------------------\n");
int num4,num5,num6;
//第二种
scanf("%d,%d,%d",&num4,&num5,&num6);
printf("%d %d %d \n",num4,num5,num6);
}
细心的大家可能会发现,为什么第二种输出的结果是错误了呢?大家仔细观察第二种scanf()函数读取变量指针值时转换说明之间的分割符是逗号,而第一种是空格符号,但第一种输出结果确是正确的。这又是为何呢?细心的同学可能会想起前几天所讲的scanf()函数在读取字符串时遇到空格就会停止读取,但这里不是这种缘由。
真正的原因是C语言标准在规定scanf()函数在读取字符串时与scanf()函数的格式化字符串严格匹配。也就是说scanf("%d,%d,%d",&num4,&num5,&num6);中格式化字符串为"%d,%d,%d",大家输入的数据(也就是scanf()读取的数据)模式相同。
scanf()函数的返回值
读取成功时返回读取的项数,该函数返回值主要用于检测和处理不匹配的输入。例子如下:
#include<stdio.h>
int main(void){
int num1,num2,num3;
int num=scanf("%d,%d,%d",&num1,&num2,&num3);
printf("%d",num);
}
空白字符
什么是空白字符?这个以后出去就不要不这样的问题!博主这里给出答案:空白字符(制表符、空格和换行符)。
小结
该篇主要用于了解C语言,总结有误的地方希望大家能够指正,有缺少的地方也希望大家指出,感觉还行的话请给个赞,给博主一点点鼓励。