小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
一、字符串简介
字符串是一个或多个字符的序列
双引号仅告知编译器它括起来的是字符串,单引号用于标识
单个字符
1.1 char类型数组和null字符
C语言没有专门用于储存字符串的变量类型,字符串都被储存在char类型的数组中。数组由连续的存储单元组成,字符串中的字符被储存在相邻的存储单元中,每个单元储存一个字符
1.2 什么是数组
可以把数组看作是一行连续的多个存储单元
数组是同类型数据元素的有序序列
char name[40]
name后面的方括号表民这是一个数组,方括号后面的40表明该数组中的元素数量
1.3 字符和字符串
字符串常量"x"和字符常量'x'不同。区别之一在于**' x '是基本类型(char),而"x"是派生类型(char数组);区别之二是"x"实际上由两个字符组成: 'x'和空字符\0**
1.4 strlen()和sizeof()区别
上一章提到了sizeof运算符,它以字节为单位给出对象的大小。strlen ()函数给出字符串中的字符长度
#include <stdio.h>
#include <string.h> //提供strlen()函数原型
#define PRAISE "Hello World!" //定义常量
int main(void)
{
char name[40];
//java中的数组是int[] arr;括号换了个位置
printf("Name:");
scanf("%s",name);
printf("%zd %zd",strlen(name),sizeof(name));
return 0;
}
结果为:
Name:pyy
3 40
PS D:\Code\C>
sizeof运算符报告,name数组有40个存储单元。但是,只有前11个单元用来储存Serendipi所以strlen ()得出的结果是1l。name数组的第12个单元储存空字符,strlen()并未将其计入
二、常量和C预处理器
有时,在程序中要使用常量。例如,可以这样计算圆的周长:circumference = 3.14159 * diameter;
这里3.1415926代表常量pi(Π)
这种情况最好用符号常量,如下计算机会自动进行替换
circumference = pi * diameter;
常量比数字表达的信息更多
owed = 0.015 * housevalue;
owed = taxrate * housevalue; 如果阅读一个很长的程序,第2条语句所表达的含义更清楚。
如何创建符号常量?
float taxrate;
taxrate = 0.015;
这样做提供了一个符号名,但是taxrate是一个变量,程序可能会无意间改变它的值。
C语言还提供了一种预处理器的方式,只需在顶部添加一行
#define TAXRATE 0.015
编译程序时,程序中所有的TA.XRATE都会被替换成0.015。这一过程被称为编译时替换(compile-timesubstitution)。在运行程序时,程序中所有的替换均已完成
2.1 const限定符
C90标准新增了const关键字,**用于限定一个变量为只读。**其声明如下:const int MONTHS = 12; ll MONTHS在程序中不可更改,值为12
这使得MONTHS 成为一个只读值。也就是说,可以在计算中使用MONTHS,可以打印 MONTHs,但是不能更改MONTHs的值。const用起来比#define更灵活
const修饰的是变量,为只读
三、printf()和scanf ()
虽然printf ()是输出函数,scanf()是输入函数。工作原理几乎一致
3.1 printf()
请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用%d,打印字符时使用%c。这些符号被称为转换说明(conversion specification),它们指定了如何把数据转换成可显示
转换说明及打印的输出结果
格式字符串中的转换说明一定要与后面的每个项相匹配!
3.1.1 printf ()的转换说明修饰符
在%和转换字符之间插入修饰符可修饰基本的转换说明
常见的:
.数字:表示的就是精度
5.2f意思是字段宽度为5,小数点后两位数字
数字:代表的是字段宽度如%4d
3.2 scanf ()
如果用scanf ()读取基本变量类型的值,在变量名前加上一个&;
如果用scanf()把字符串读入字符数组中,不要使用&。
3.2.1 scanf ()的转换说明修饰符
简单了解一下...
这本书也太tm难学了!!!
四、关键概念
字符串是一系列被视为一个处理单元的字符。
char name [ 30]; 要确保有足够多的元素来储存整个字符串(包括空字符)
strlen()函数(声明在string.h头文件中)可用于获得字符串的长度(末尾的空字符不计算在内)。scanf ()函数中的转换说明是%s时,可读取一个单词。
C预处理器为预处理器指令(以#符号开始)查找源代码程序,并在开始编译程序之前处理它们。
printf()和scanf ()函数对输入和输出提供多种支持。两个函数都使用格式字符串,其中包含的转换说明表明待读取或待打印数据项的数量和类型。另外,可以使用转换说明控制输出的外观:字段宽度、小数位和字段内的布局。
五、编程练习
代码和结果都放在代码块中了!
1.c
#include <stdio.h>
int main(void)
{
char fname[20], lname[20];
printf("Please enter your first name: ");
scanf("%19s", fname); //19是字段长度
printf("Please enter your last name: ");
scanf("%19s", lname);
printf("Hello! %s, %s.\n", fname, lname);
return 0;
}
2.c
#include <stdio.h>
#include <string.h>
int main(void)
{
int len = 0;
char name[20];
printf("Please enter your name:");
scanf("%19s", &name);
len = strlen(name);
printf("Print your name:\n");
printf("a.\"%s\"\n", name);//正常的打印
printf("b.\"%20s\"\n", name); //在宽度为20的字段右端打印name,包括双引号
printf("c.\"%-20s\"\n", name); //从字段的左侧开始打印该项
printf("d.%*s\n", len + 3, name);
return 0;
}
Please enter your name:pyy
Print your name:
a."pyy"
b." pyy"
c."pyy "
d. pyy
3.c
#include <stdio.h>
int main(void)
{
float num;
printf("Please enter a float number:");
scanf("%f", &num);
printf("The input is %.1f or %.1e.\n", num, num);//表达两种计数法.1f表示小数点后两位
//.1e表达浮点数的计数法
return 0;
}
Please enter a float number:2.3
The input is 2.3 or 2.3e+000.
这是C语言的浮点数常量的科计数法
2.3e+02
2.3*10的二次方
1.0e+003
1.0*10的三次方
4.c
#include <stdio.h>
#define LEN 30
int main(void)
{
float heigh;
char name[LEN];
printf("Please enter your name:");
scanf("%29s", &name);//接受name
printf("Hello! %s, how tall you are(inch):", name);
scanf("%f", &heigh);//接受height
printf("%s, you are %.3f feet tall.\n", name, heigh / 12.0);
return 0;
}
Please enter your name:pyy
Hello! pyy, how tall you are(inch):178
pyy, you are 14.833 feet tall.
5.c
#include <stdio.h>
#define BIT 8
int main(void)
{
float speed, size, time;
printf("Please enter net speed(Mbit/s):");
scanf("%f", &speed);
printf("Please enter file size(MB):");
scanf("%f", &size);
time = size * BIT / speed; //b和B转换单位是8
printf("At %.2f megabits per secnod, ", speed);
printf("a file of %.2f megabytes ", size);
printf("downloads in %.2f seconds.\n", time);
return 0;
}
简单不作详细解释
Please enter net speed(Mbit/s):10
Please enter file size(MB):20
At 10.00 megabits per secnod, a file of 20.00 megabytes downloads in 16.00 seconds.
6.c
#include <stdio.h>
#include <string.h>
int main(void)
{
int x, y;
char fname[20], lname[20];
printf("Please enter your first name: ");
scanf("%19s", &fname);
printf("Please enter your last name: ");
scanf("%19s", &lname);
x = strlen(fname);
y = strlen(lname);
printf("%s %s\n", fname, lname);
printf("%*d %*d\n", x, x, y, y);//后面会详细解释*的作用,作用是与尾对齐
printf("%s %s\n", fname, lname);
printf("%-*d %-*d\n", x, x, y, y);
return 0;
}
Please enter your first name: pyy
Please enter your last name: caq
pyy caq
3 3
pyy caq
3 3
7.c
#include <stdio.h>
#include <float.h>
int main(void)
{
float f_value = 1.0 / 3.0;
double d_value = 1.0 / 3.0;
//1、%lf 双精度浮点型,也就是double型的格式,默认保留6位小数。
//2、%.2lf 同上,不过限制了,值保留2位小数。
printf("1.0 / 3.0 display 6 decimal places:\n");
printf("f_value = %.6f\nd_value = %.6lf\n", f_value, d_value);
printf("\n1.0 / 3.0 display 12 decimal places:\n");
printf("f_value = %.12f\nd_value = %.12lf\n", f_value, d_value);
printf("\n1.0 / 3.0 display 16 decimal places:\n");
printf("f_value = %.16f\nd_value = %.16lf\n", f_value, d_value);
printf("\nfloat and double maximum significant digits:\n");
printf("FLT_DIG = %d, DBL_DIG = %d\n", FLT_DIG, DBL_DIG);
//↑FLTDIG代表float有效十进制数字位数;
//↑DBL_DIG代表double有效十进制数字位数;
return 0;
}
1.0 / 3.0 display 6 decimal places:
f_value = 0.333333
d_value = 0.333333
1.0 / 3.0 display 12 decimal places:
f_value = 0.333333343267
d_value = 0.333333333333
1.0 / 3.0 display 16 decimal places:
f_value = 0.3333333432674408
d_value = 0.3333333333333333
float and double maximum significant digits:
FLT_DIG = 6, DBL_DIG = 15