程序运行时,其值不能被改变的量称为常量。
常量类型
整型常量 如:1000、0、-162
实型常量
字符常量
普通字符 单撇号括起来的一个字符。
转义字符 以字符\
开头的字符序列
常见转义字符 | 输出结果 |
---|---|
\n | 换行 |
\t | 将光标移到一下Tab键位置 |
'&" | 输出单撇号&双撇号 |
详尽转义字符以及
\ascii码
表格 书本P40
字符串常量
用双撇号将若干个字符括起来。如:“boy”、“123”
单撇号内只能包含一个字符,双撇号内可以包含一个字符串
符号常量
用#define
指令,指定用一个符号名称代表一个常量。如#define PI 3.1416 //注意没有分号
在需要改变程序中多出用到的同一个常量时,能做到“一改全改”
变量必须先定义、后使用。
常变量存在期间其值不能改变。
常变量定义
在定义变量时,前面加一个关键字const
。如:const int a=3;
整型数据
基本整型(int)
基本整型为整数。如100、10、0、-10
基本整型定义:int b;
长整型(long int)
长整型和基本整型都是整数。区别在于长整型可存储范围比基本整型大。
长整型定义:long int b;
整型数据默认都是带有符号的(正负号),可在定义整型数据时前加unsigned
定义无符号整型数据类型(只有正值)
字符型数据
字符与字符代码
ASCII字符集内全部都是字符,包含字母、数字、标点、转义等等字符。
每一个字符都有对应的ASCII整数。
字符变量
字符变量用char
定义。如:char a='?';
字符变量实际上是一个字节的整型变量,也就是对应的ASCII整数。因此也可选择输出十进制整数。如:
printf("&d\t%s\n",c,c)//省略定义字符变量 c='?'
浮点型数据
浮点型数据就是具有小数点的实数。
单精度浮点型(float
)
float型数据定义:float a;
双精度浮点型(double)
相比于单精度浮点型可记录的小数位数更多。
double型数据定义:double a;
运算符 | 含义 | 举例 | 结果 |
---|---|---|---|
+ | 正号 | +a | a的值 |
- | 负号 | -a | a的算术负值 |
* | 乘法 | a*b | a和b的乘积 |
/ | 除法 | a/b | a除以b的商 |
% | 求余 | a%b | a除以b的余数 |
+ | 加法 | a+b | a和b的和 |
- | 减法 | a-b | a和b的差 |
自增(++)、自减(–)运算符作用是使变量的值加1或减1。
i++
、i--
:先使i
的值加(减)1,在调用i
++i
、--i
:先调用i
,在使i
的值加(减)1
+ - * /
运算两个数中有一个数为float
或double
,结果为double
int
与float
或double
运算,结果为double
char
)型与整形数据运算,就是把字符的ASCII码与整形数据进行运算利用强制类型转换运算符将一个表达式转换成所需类型。如:(double)a
一般形式为(类型名)(表达式)
在强制类型转换时,得到一个所需类型的中间数据,而原来变量的类型未变化。例如
a=(int)x;//a为int x为float
,其中的x依然为原值float型。
赋值运算符
赋值符号=
就是赋值运算符。如:a=3//省略定义a为int
复合的赋值运算符
在赋值符前加上其他运算符构成复合的运算符。
常见符合运算符有+=
、-=
、*=
、/=
(定义与python复合运算符相同)
赋值表达式
赋值运算符将一个变量和一个表达式连接起来的式子称为“赋值表达式”,一般形式为:变量 赋值运算符 表达式
。如:a=3*5;
赋值过程类型转换
使用printf
函数输出数据
一般格式为printf("格式控制",输出表列);
如:printf("%s\n",a);//char a="hello"
""
括起来的一个字符串,包括两个信息:
%
和格式字符组成。如:%d
、&f
等。作用是将输出的数据转换为指定的格式后输出。格式字符
d格式符%d
在输出时,按十进制整型数据的实际长度输出,正数的符号不输出。可以在格式声明中指定输出数据的域宽(所占的列数)。如:%5d
输出长整型数据:%ld
;
c格式符%s
用来输出一个字符。也可以指定域宽。
s格式符%s
用来输出一个字符串。
f格式符
用来输出实数(各种浮点数),以小数形式输出。
基本型float,用%f
实数整数部分全部输出,小数部分输出6位
指定数据宽度和小数位数%m.nf
指定输出数据占m列,其中包含n位小数,采取四舍五入原则处理。
输出数据向左对齐%-m.nf
当数据长度不超过m时,数据向左靠,右端补空格。
输出双精度浮点数据:%lf
e格式符
用格式声明%e
指定以指数形式输出实数。其中e也可以写成E。
其他格式符
o格式符
以八进制整数形式输出
x格式符
以16进制整数形式输出
用scanf
函数输入数据
一般形式:scanf(格式控制,地址表列)
,其中格式控制与printf
相同,地址表列是由若干个地址组成的表列。如:scanf("%s",&a)//省略定义a为字符型
格式声明:输入数据时需要符合的字符串格式。
如果在格式控制字符串除了格式声明之外还有其他字符,则在输入数据时在对应的位置上也应输入与这些字符相同的字符。如:scanf("a=%s",&a)
,应输入a="c code"
,则变量a的值才为"c code",若缺失会产生不可思议的结果。
地址表列不是变量名组成的列表,而是变量对应的地址。即应该填入&a
,而非a
若输入空格回车Tab键等等与数据类型不相符合的非法字符,则认为该数据结束
putchar
输出一个字符
#include
int main()
{
char a='A';
putchar(a);//填入字符变量名
putchar('\n');//也可填入输出单个的字符
return 0;
}
getchar
输入一个字符
#include
int main()
{
char a;
a=getchar();//字符变量承接输入字符
return 0;
}
if (表达式) 语句1;
(没有else子句)if (表达式) 语句1; else 语句2;
(有else子句)if (表达式) 语句1; else if (表达式2) 语句2;else if(表达式3) 语句3;else 语句n;
(在else部分嵌套n层if语句)六种关系运算符
关系运算符 | 描述 | 优先级 |
---|---|---|
< | 小于 | 高 |
<= | 小于等于 | 高 |
> | 大于 | 高 |
>= | 大于等于 | 高 |
== | 等于 | 低 |
!= | 不等于 | 低 |
关系表达式
用关系表达式将两个数值或数值表达式连接起来的式子。如:a
关系表达式的值为一个逻辑值(真、假)。其中真
用1
代表,假
用0
代表
逻辑运算符
运算符 | 含义 | 举例 | 说明 |
---|---|---|---|
&& | and | a&&b | a和b皆为真,则结果为真 |
|| | or | a||b | a和b两者若有真,则结果为真 |
! | not | !a | 若a为真,则结果为假 |
逻辑表达式
逻辑表达式的值应该是一个逻辑量“真”或“假”,分别用数值“1”和“0”代表;
表达式自左向右求解。
if(a>b) max=a;else max=b;
这个选择结构可以改写为条件表达式max=(a>b)?a:b
。
一般形式为:表达式1?表达式2:表达式3
?
、:
为条件运算符。两者必须组合使用
max(a>b)?a:b
为条件表达式。如果(a>b)?
条件为真,值等于a,否则值等于b
if语句嵌套
if()
//嵌套if_1
if() 语句1
else() 语句2
else()
//嵌套if_2
if() 语句3
else() 语句4
使用花括号{}
来确定配对关系
switch
语句实现多分支选择结构
#include
int main()
{
char grade;
scanf("%c",&grade);
printf("Your score:");
switch(grade)
{
case'a':printf("100~85\n");break;
case'b':printf("84~60\n");break;
case'c':printf("59~0\n");break;
default:printf("enter data error!\n");//以上不符合则执行这项
}
return 0;
}
一般形式为:
switch(表达式)
{
case 常量1:语句1 //确保常量之间各不相同
case 常量2:语句2
default: 语句n+1 //处理无匹配情况,可选添加该项
}
多个case
可以共用一个语句
switch(表达式)
{
case 常量1: //注意无;
case 常量2:语句2
default: 语句n+1
}
#includ
int main()
{
int i=1,sum=0;
while(i<100)
{
sum+=1;
i++;
}
printf("sum=%d\n",sum);
return 0;
}
一般形式:while(表达式)语句
。表达式被称为循环条件表达式;语句被称为循环体。
只要循环条件表达式为真,就执行循环体语句。
int i=1;//设置初始值i=1
do//循环开始
{
printf("%d",i++);//循环体
}
while(i<100);//循环条件表达式
执行do
的循环体语句,然后在while
循环条件表达式检查i
的值,判断是否继续循环(先无条件执行循环体,之后判断循环条件)
一般形式:
do
语句
while(表达式)
for(i=0;i<100;i++)//控制循环次数
printf("%d",i);//执行循环体
一般形式:for(表达式1;表达式2;表达式3) 语句
也可归结为以下形式:for(循环变量赋初值;循环条件;循环变量增值) 语句
表达式123均可在一定条件下省略,但必须保留分割的;
当表达式中含有多个小表达式,用,
分隔
for循环可以与while循环无条件转换
while
内层循环
while()
{
···
while()
{
···
}
}
do···while
内层循环
do
{
···
do
{
···
}
while(···)
}
while(···)
for
内层循环
for(;;)
{
···
for(;;)
{
···
}
}
while
、do···while
循环
while()
{
···
do{···}
while(···);
}
for
、while
循环
for(;;)
{
···
while(){···}
}
do···while
、for
循环
do{
···
for(;;){···}
}
while();
break
语句
提前终止循环,将流程跳到循环体之外,接着执行循环体下面语句
continue
语句
提前结束本次循环,接着执行下一次循环
#include
int main()
{
int i;
int f[20]={1,1};//定义数组前两元素初始值
for(i=2;i<20;i++)
{
f[i]=f[i-2]+f[i-1];
}
for(i=0;i<20;i++)
{
if(i%5==0) printf('\n');//控制每输出5个数后换行
printf("%12d",f[i]);
}
printf('\n');
return 0;
}
定义一维数组
一般形式为:类型符 数组名[常量表达式]
。如:int a[10]
引用一维数组元素
数组名 [下标]
其中下标也可以用常量表达式表示
一维数组初始化
int a[3]={1,2,3};
int a[10]={1,2,3,4};
int a[10]={0};
int a[]={1,2,3,4,5}//不指定数组长度定义时,必须给数组全部元素赋值
#include
int main()
{
int a[2][3]={1,2,3,4,5,6};
int b[3][2]=,i,j;
printf("array a:\n");
for(i=0;i<=1;i++)//提取a的行
{
for(j=0;j<=2;j++)//提取a的列
{
printf("%5d",a[i][j]);
b[j][i]=a[i][j];//赋值给b数组
}
printf("\n");
}
printf("array b:\n");
for(i=0;i<=2;i++)
{
for(j=0;j<=1;j++)
{
printf("%5d",b[i][j]);
}
printf("\n")
}
}
二维数组定义
一般形式为类型说明符 数组名[常量表达式][常量表达式]
。如:float a[20][20];
引用二维数组元素
引用形式为数字名 [下标][下标]
二维数组初始化
int a[2][3]={{1,2,3},{4,5,6}};
int a[2][3]={1,2,3,4,5,6};
int a[2][3]={[1],[4]};
int a[][3]={1,2,3,4,5,6};
定义字符数组char a[10];
字符数组初始化
定义时依次全部赋值。char a[2]={'h','i'};
定义时赋值个数小于数组长度,其与元素自动定位空字符\0
不指定字符数组长度。如:char a[]={'h','i'};
也等价于char a[]="hi";
、char a[]={"hi"};
二维字符数组定义与初始化与上相同
引用字符数组元素
一般形式:字符数组名 [下标]
。可以引用字符数组中的一个元素,得到一个字符。
字符串、字符数组定义结束标志
以字符\0
作为结束标志。
用字符数组存储字符串常量会自动加一个\0
作为结束符
在使用scanf
函数输入多个字符串,则应该输入时以空格分隔
处理字符串的函数
puts
输出字符串
puts(字符数组)
。如:puts(str); //char str[]="china"
puts
输出时将字符串结束标志/0
转换成\n
gets
输入字符串
gets(字符数组)
。如:gets(str); //chat str[10]
strcat
链接字符串
一般形式为strcat(字符数组1,字符数组2)
。如:new_str=strcat(str_1,str_2); //将str_2链接到str_1后面
务必确保str_1
有足够的数组长度容纳str_2
``
strcpy
复制整体字符串
一般形式strcpy(字符数组1,字符数组2)
。如:strcpy(str1,str2) //将str_2复制到str_1
确保str_1
有足够的数组长度
strncpy
复制前N个字符串
strncpy(str_1,str_2,2)
strcmp
字符串比较
strcmp(字符串1,字符串2)
strlen
测量字符串长度
strlen(字符数组)
strlwr
转换为小写
strlwr(字符串)
strupr
转换为大写
strupr(字符串)
定义函数
定义无参函数
类型名 函数名()
{
函数体
}
或
类型名 函数名(void)
{
函数体
}
定义有参函数
类型名 函数名(形参表列)
{
函数体
}
定义空函数
类型名 函数名()
{}
调用函数
函数名 (实参表列)
。如:print_star(); //调用无参函数
、c=max(a,b); //调用有参函数
函数调用时数据传递
形参和实参
在定义函数函数名后括号内的变量名为形式参数
调用函数填在函数名后括号内的变量为实际参数
函数的返回值
return
语句获得函数递归
#include
int main()
{
int fac(int n);//fac函数声明
int n,y;
printf("input an interger number:");
scanf("%d",&n);
y=fac(n);
printf("%d!=%d\n",n,y);
return 0;
}
int fac(int n)
{
int f;
if(n<0)
printf("n<0,data error!");
else if(n==0||n==1)
f=1;
else f=fac(n-1)*n;
return f;
}
一维数组名作为函数参数
#include
int main()
{
float average(float array[10]);
float score[10],aver;
int i;
printf("input 10 scores:\n");
for(i=o;i<10;i++)
{
scanf("%f",&score[i]);
}
printf("\n");
aver=average(socre);
printf("average score is %5.2f\n",aver);
return 0;
}
float average(float array[10])
{
int i;
float aver,sum=array[0];
for(i=0;i<10;i++)
{
sum+=array[i];
}
aver=sum/10;
return aver;
}
[]
average
函数时,声明形参数组大小为10,实际上指定大小是不起作用的。C语言会将实参数组首元素地址传给形参数组名,两者具有统一地址,同一存储单元多维数组名作为函数参数
#include
int main()
{
int max_value(int array[][4]);
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
printf("Max value is %d\n",max_value(a));
return 0;
}
int max_value(int array[][4])
{
int i,j,max;
max=array[0][0];
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
if(array[i][j]>max)max=array[i][j];
}
return max;
}
内部函数
一个函数只能被本文件中其他函数所调用,为内部函数。
外部函数
调用外部函数,在头信息中加上#include"filename"
相当于include
,同时声明函数时加上extern
,即extern int fun(int a,int b);
file1.cpp
#include
#include"file2.cpp" //导入外部文件
int main()
{
extern void show();
show();
return 0;
}
file2.cpp
#include
void show()
{
printf("hello, world\n");
}
局部变量
存储类别
自动变量(auto变量)
在调用函数时,系统分配存储空间,在函数结束时自动释放存储空间
int f(int a)
{
auto int b,c=3;
}
实际上auto
通常省略,则暗指为“自动存储类别”
静态局部变量(static局部变量)
在函数调用结束后不消失,继续保存其值,需要用static
声明
#include
int main()
{
int f(int);
int a=2,i;
for(i=0;i<3;i++)
{
printf("%d\n",f(a));
}
return 0;
}
int f(int a)
{
int b=0;
static int c=3;//不会重新定义c为3,而是保持c其值
b+=1;c+=1;
return (a+b+c);
}
全局变量
在函数之外定义的变量,有效范围从定义变量处到本源文件结束
存储类别
使用关键字extern
对变量作外部变量声明,将变量作用域扩展到此位置
#include
int main()
{
int max();
extern int A,B,C;
printf("Please enter three interger numbers:\n");
scanf("%d%d%d",&A,&B,&C);
printf("max is %d\n",max());
return 0;
}
int A,B,C;
int max()
{
int m;
m=A>B?A:B;
return m;
}
如果全局变量与局部变量同名,在函数范围内全局变量被局部变量屏蔽,相当于全局变量不存在
地址指向变量单元,地址形象化称为指针。
直接用变量名访问,称为直接访问;通过地址访问变量,称为间接访问
专门存储地址(指针)的变量为指针变量,其值为地址(指针)
定义指针变量:一般形式为类型名 *指针变量名
。
*
表示该变量是指针型变量,但是存储地址的是指针变量名
引用指针变量
&
取址运算符;*
指针运算符;
p=&a; //把a的地址赋给指针变量p
printf("%d\n",*p); //输出指针变量对应的值
printf("%o",p);
指针变量作为函数参数
#include
int main()
{
void swap(int *p1;int *p2);
int a,b;
int *pointer_1,*pointer_2;
printf("please enter a and b:");
scanf("%d,%d",&a,&b);
pointer_1=&a;pointer_2=&b;
if(a<b) swap(pointer_1,poiter_2);
printf("max=%d,min=%d\n",a,b);
return 0;
}
void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;*p2=temp;//交换p1,p2
}
定义指针执行数组
int a[10];
int *p;
p=&a[0];//把a[0]元素地址指向指针变量
/*指向语句也可这样写
p=a;
将a数组首元素地址指向指针变量*/
引用数组指针运算
在指针已指向一个数组元素时,可以进行以下运算:加减一个整数,自加自减运算。
指针运算加减一个整数,反应为指向上一个或下一个元素的地址
通过指针引用数组元素
#include
int main()
{
int a[10];
int *p,i;
printf("please enter 10 interger numbers:");
for(i=0;i<10;i++) scanf("%d",&a[i]);
for(p=a;p<(a+10);p++) printf("%d",*p);
return 0;
}
表现形式 | 含义 | 值 |
---|---|---|
a | 二维数组名,指向一维数组a[0],即0行起始地址 | 2000 |
a[0]、*(a+0)、*a | 0行0列元素位置 | 2000 |
a+1、&a[1] | 1行起始位置 | 2016 |
a[1]、*(a+1) | 1行0列元素a[1][0]的地址 | 2016 |
a[1]+2、*(a+1)+2、&a[1][2] | 1行2列元素a[1][2]的地址 | 2024 |
*(a[1]+2)、*(*(a+1)+2)、a[1][2] | 1行2列元素a[1][2]的值 | 值为13 |
#include
int main()
{
void average(float *p,int n);
void search(float (*p)[4],int n);
float score[3][4]={69,44,87,97,75,66,85,77,64};
average(*score,12);
search(score,2);
return 0;
}
void average(float *p,int a)
{
float *p_end;
float sum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)
{
sum+=(*p);
}
aver=sum/n;
printf("average=%5.2f\n",aver);
}
void search(float (*p)[4],int n)
{
int i;
printf("the score of no.%d are:\n",n);
for(i=0;i<4;i++)
printf("%5.2f",*(*(p+n)+i));
printf("\n");
}
| 二维数组名,指向一维数组a[0],即0行起始地址 | 2000 |
| a[0]、(a+0)、*a | 0行0列元素位置 | 2000 |
| a+1、&a[1] | 1行起始位置 | 2016 |
| a[1]、(a+1) | 1行0列元素a[1][0]的地址 | 2016 |
| a[1]+2、*(a+1)+2、&a[1][2] | 1行2列元素a[1][2]的地址 | 2024 |
| *(a[1]+2)、*(*(a+1)+2)、a[1][2] | 1行2列元素a[1][2]的值 | 值为13 |
#include
int main()
{
void average(float *p,int n);
void search(float (*p)[4],int n);
float score[3][4]={69,44,87,97,75,66,85,77,64};
average(*score,12);
search(score,2);
return 0;
}
void average(float *p,int a)
{
float *p_end;
float sum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)
{
sum+=(*p);
}
aver=sum/n;
printf("average=%5.2f\n",aver);
}
void search(float (*p)[4],int n)
{
int i;
printf("the score of no.%d are:\n",n);
for(i=0;i<4;i++)
printf("%5.2f",*(*(p+n)+i));
printf("\n");
}