C语言知识点总体梳理(知识点)

C语言知识点总体梳理

一、数据的表现形式

1、常量

(1)整型常量

(2)实型常量:十进制小数形式(由数字和小数点组成)、指数形式(12.34e5,e或E之前和之后必须有数字、之后的数字必须是整数

E表示10的多少次方,次方跟在E后

(3)字符型常量:普通字符(单引号括起来的单个字符,以ascii码值存放,)、转义字符(以\开头的字符序列P40)

(4)字符串常量:双引号括起来的任意字符

(5)符号常量:用#define指令,指定用一个符号名称代表一个常量,好处见名知意、一改全改,注意符号常量不占内存,编译后,符号不存在
#define PI 3.1416 //行末没有引号

案例:区分1、‘1’、“1”,分别是整形常量 、字符常量 、字符串

2、变量

(1)先定义后使用

(2)变量有三要素,变量名,变量地址,变量的值

(3)标识符(变量的名字):字母、数字、下划线,不能以数字开头,区分大小写,自定义的标识符不能是关键字

二、数据类型

数据类型(决定了数据占用的内存空间及存储形式,决定了数据可以参与的运算,C标准并没有规定每种类型占用的字节数,由编译系统自行决定(P45)、sizeof运算符可以测量变量或类型的长度,占用的字节数,决定了可以表示数的范围

1、各种数据类型

(1)整型

(2)字符型:字符型在一定范围内可以和整型通用(P48)

(3)实型(浮点型) :实数以指数形式存储

注意:只有整型、字符型可以使用signed或unsigned修饰,实型不可以,无符号整型用%u输出

用有限的单元不能完全精确地存储一个实数

2、确定常量的类型

2----int
2L----long
3.4----double
3.4f----float

3、数据的输入输出(C语言本身不提供输入、输出操作,由库函数完成)

(1)输入

1) int scanf(char * format,args,…);
scanf(“a=%d”,&a); (P75注意事项)

char * 相当于字符串格式,用字符数组进行存放----char ch[10]=“a=%d”;

格式控制字符串:以%开头的格式控制符(P74,与输入项对应),以及其他普通字符(原样输入
读入double类型的数值的时候后面别忘了加f
输入项(地址表列):变量的地址

2) int getchar(); ------从标准输入设备输入一个字符空格、回车、tab等都是有效字符

char c=getchar()

#include <stdio.h>
#define SIZE 10
void findmax( int *px,int n,int *pmax );
int main()
{
    
    
    int a = getchar();
    printf("a=%d\n",a);
    
    char c = getchar();
    printf("c=%c\n",c);
}

在这里插入图片描述

如果输入的是数字,自动转换为字符型

(2)输出

int printf(char * format,args,…) 返回输出字符的个数
printf(“a=%d”,a);

格式控制字符串:以%开头的格式控制符(与输出项对应),以及其他普通字符(原样输出)

输出项:变量

(3)int putchar(char ch); 输出一个字符

putchar(getchar())
char c=’y’;
putchar©;

#include <stdio.h>
void findmax( int *px,int n,int *pmax );
int main()
{
    
    
    int a = getchar();
    putchar(a);
    
    char c = getchar();
    putchar(c);
    printf("\n");
}

在这里插入图片描述

4、sizeof的使用

#include <stdio.h>
#define SIZE 10
void findmax( int *px,int n,int *pmax );
int main()
{
    
    

    printf("一个int类型的值所占的字节为:%lu\n",sizeof(int));
    printf("一个float类型的值所占的字节为:%lu\n",sizeof(float));
    printf("一个char类型的值所占的字节为:%lu\n",sizeof(char));
    printf("一个double类型的值所占的字节为:%lu\n",sizeof(double));
    int a[5];
    printf("一个int类型的数组:a[5]所占的字节数为:%lu\n",sizeof(a));
    printf("a数组的长度为:%lu\n",sizeof(a)/sizeof(int));
    double b[3][4];
    printf("一个double类型的二维数组:b[3][4]所占的字节数为:%lu\n",sizeof(b));
    printf("b数组的长度为:%lu\n",sizeof(b)/sizeof(double));
}

在这里插入图片描述

三、运算符(对数据进行加工)运算规则、优先级结合性、表达式的值

1、算术运算符

1) 算术运算符:+、-、*、/(两个整数相除结果为整数)、%(操作数必须为整数)、++、 – (只能用于变量,分清前缀后缀)

int  a=3,c;
c=a++;  c= 3 a=4   ==>c=a; a++
c=++a;   c=4,a=4    ==>a++ ;c=a

2.5/2=1.25
5/2=2
(a+b)++ 错误

2) 结合性:自左至右
3) 算术表达式的值:计算结果

2、赋值运算符

1) 基本赋值运算符=,将右侧的值赋给左侧的变量
int a,b; a+b=5(错误)

2) 复合赋值运算符,例如+=
a+=b<===> a=a+(b)
括号不要忘记 a一定是变量,b是表达式(一个变量或常量是最简单的表达式)

int a=2,b=3,c;
c*=a+b; ===>c=c*(a+b) 一定别忘记括号

3) 结合性:自右至左

int a,b,c=8;a=b=c ===>a=(b=c)

int a,b,c; a=b+1=c+2;===>a=(b+1=c+2) 错误
int a=b=3; 错误,b未声明
int a=3,b=3; 或 int a,b; a=b=3;正确

4) 赋值表达式的值:赋值运算符左侧变量的值
5) 赋值运算符两侧的类型转换:两侧的类型都是数值型,以左侧变量的类型为准,由系统自动完成
例如

double a=1; ==>a=1.0

int a=3.4; ==>int a=(int)3.4 -->a=3(有精度损失的警告,但不影响运行,但在java中报编译错误)

3、关系运算符

1)符号 、!、=、 >、 <、 >=、 <=

2)运算规则 注意区分=和==

3)结合性:自左至右

4)关系表达式的值 1(表达式成立,真)或0(表达式不成立,假)

int x=5;
10<=x<=99 关系表达式自左至右求解,先求10<=x,则表达式不成立表达式的值为0 ,接下来继续求解0<=99 ,结果为1

不论x的值是多少,表达式10<=x<=99的值恒为1

4、逻辑运算符

1)符号 &&逻辑与、 ||逻辑或(双目运算符)、 !逻辑非(单目运算符)

2)运算规则 (a,b可以为一个常量或变量或表达式)

a&&b,a,b两者同为真(非零为真,否则为假)时,结果为真

a||b,a,b同时为假,结果为假,否则结果为真

!a,取反,a为真,结果为假,a为假结果为真

系统如何判断一个量的真假非零为真,0为假

系统如何表示真假:1–真 0----假

3)结合性:自左至右

4)逻辑表达式的值为1或0,成立(真)为1,否则为0

a=3,b=4,c=5

((a+b)>c)&&(b==c) 逻辑表达式 值为0
a||((b+c)&&(b-c)) 短路现象 1
((!(a>b))&&(!c))||1 不存在短路现象 1
(!(x=a))&&(y=b)&&0 短路现象 0
((!(a+b))+c-1)&&(b+c/2) 1

5)短路现象:存在于&&和||中,

a&&b,当a为假的时候,不需要计算b的值,就可以直接得到整个逻辑表达式的值为假,这个现象称为短路现象

a||b,当a为真的时候,不需要计算b的值,就可以直接得到整个逻辑表达式的值为真,这个现象称为短路现象

例如

a=3,b=4,c=5
x=1,y=2则执行下面的表达式后,x=3,y=2(短路现象)
(!(x=a))&&(y=b)&&0

5、条件运算符

符号表达式1?表达式2:表达式3 二分支结构

运算规则,求解表达式1,为真则求解表达式2,并将表达式2的结果作为整个条件表达式的结果,否则求解表达式3,并将表达式3的结果作为整个条件表达式的结果

等价于二分支结构

if(表达式1)
表达式2
else
表达式3

6、逗号运算符 ,

1)规则:自左至右求解,并将最后一个表达式的值作为整个逗号表达式的值

7、间接引用运算符*:后面只能跟地址,表示的是地址指向的内存

int a; ---------- *&a<===>a

8、地址运算符 &:后面只能跟变量

int a;int *p=&a; &a=====p 均指整型变量a的地址
int *p; &p-----代表指针变量的地址,合法

三、流程控制

1、顺序

2、选择(分支)

(1)if语句

语法:

if(表达式)
   语句

注意:
1) 表达式是任意合法的表达式,表达式后不能加分号
2) 语句为一条语句,如果有多条,需要用大括号构成复合语句
3)执行:如果表达式成立(为真,非零为真),则执行语句

(2)if…else语句

语法:

if(表达式)
   语句1
   else
   语句2

注意:
1)表达式是任意合法的表达式
2)语句1、2为一条语句,如果有多条,需要用大括号构成复合语句
3) else表示的情况与if完全相反,并且else必须和if配对使用
4) 执行:如果表达式成立(为真,非零),则执行语句1,否则执行语句2
案例,else必须和if配对

程序报错

else总是和离它最近没有配对的if配对,可以用大括号改变配对(P108,第七题),else不能单独使用

(3)if语句的嵌套

(4)switch 语句—多分支语句(开关语句)

语法:

switch(表达式)
{
    
    
	case 常量表达式1:语句1case 常量表达式2:语句2case 常量表达式3:语句3;
	….
	default:语句n;
}

注意:

1)表达式可以为任意合法的表达式,但其值必须为整型(字符型)
2)case后面必须是常量表达式,并且不能重复
3)case后面的语句可以有多条,不必加括号
4)执行:首先计算表达式的值,然后将其和case后面的常量比对,如果相等,则执行case后面的语句,一直到结束,除非遇到break语句,结束swtich语句
5)多个case可以共用一条语句
6)break ,default不是必须的

3、循环结构——重复,次数确定或不确定

循环变量的初始值、循环条件、循环体(一条语句,循环体中有使循环条件趋于不成立的语句)

(1)While语句

语法

while(表达式)//循环条件,后面没有分号
{
    
    
       语句  //循环体,包含使循环条件不成立的语句
}

注意:

1)表达式为任意合法的表达式,当表达式为真时,执行循环体,当表达式为假,结束循环,循环体最少执行0次

(2)do…while语句

语法:

do
{
    
    
  语句//循环体,包含使循环条件不成立的语句
}while(表达式); //循环条件,后面有分号

注意:
1)表达式为任意合法的表达式,先执行语句,然后判断循环条件,当表达式为真时,继续执行循环体,当表达式为假,结束循环,循环体至少执行1次

(3)for语句

语法:

for(表达式1;表达式2;表达式3)//后面没有分号
{
    
    
	语句
}

注意:
先执行表达式1,然后判断表达式2,如果为真则执行语句,然后执行表达式3,如果为假则结束循环

三个表达式都可以省略,分号不可以省略

表达式1通常为循环初始条件,表达式3通常为循环变量的改变

4、break\continue

break 结束其所在的循环

continue结束本次循环,接着进行下一次循环条件的判断

continue在for循环中会接着执行表达式3,然后判断循环条件

典型案例:求和、计数器、分离各个位数字、素数、斐波那契数列、每行输出几个数、输入一行数以#号结束(P136)、菱形图案、判断几位数

四、数组 批量同类型数据,数组元素在内存中连续存放,数组名代表数组首地址,是一个地址常量、构造类型(根据一定的规则,利用基本类型构造而成)

1、一维数组

(1)数组声明

语法:
类型 数组名[常量表达式];

注意:
1) 类型是任意合法的类型
2) []里一定是常量,代表数组元素的个数

(2)数组初始化(定义的同时赋值)

Int a[10]={1,2,3,4}//可以全部赋值,可以部分赋值(其余元素都是默认值),如果全部赋值,则数组大小可以省略

例如:Int a[]={1,2,3,4}等价于int a[4]={1,2,3,4}

注意:除了初始化时可以给所有元素赋值,否则,定义完数组时,只能逐个元素赋值

Int a[10];//10代表是数组元素的个数
a[10]={1,2,3,3};//错误10代表数组元素的下标
a={1,2,4};//错误

(3)数组元素的引用

语法:
数组名[下标]

注意:
不能一次性引用数组元素,只能逐个引用,下标从0到数组大小减1,通常利用循环遍历数组

(4)常见算法

遍历、最值、排序、逆置、增删改查

2、二维数组:一维数组的数组

存放批量同类型数据,数组元素在内存中连续存放(按行存放,第一行存放完再存放第二行…),数组名代表数组首地址,是一个地址常量

(1)数组声明

语法:
类型 数组名[常量表达式] [常量表达式];

注意:
1)类型是任意合法的类型
2)[]里一定是常量,代表数组元素的个数

(2)数组初始化(定义的同时赋值)

Int a[10][3]={ {1,2,3,4},{}}//可以全部赋值,可以部分赋值(其余元素都是默认值),如果全部赋值,则数组第一维大小可以省略

例如:
Int a[2][3]={1,2,3,4,5,6}
等价于a[][3]={1,2,3,4,5,6}

注意:除了初始化时可以给所有元素赋值,否则,定义完数组时,只能逐个元素赋值

(3)数组元素的引用

语法
数组名[行标][列标]

通常用双层循环遍历二维数组,外层控制行,内层控制列

(4)常见算法

遍历、最值、转置(行列互换)、上下三角

3、字符数组:存放字符

(1)数组声明语法:

char 数组名[常量表达式];

(2)初始化

Char a[10]={‘h’,’i’}//可以全部赋值,可以部分赋值(其余元素都是默认值),如果全部赋值,则数组大小可以省略

Char ch[]={“hello”} ==>char ch[]=”hello”//字符串结束标志\0 数组ch长度为6(包含\0)
字符串结束标志\0,但字符数组可以不包含\0

(3)数组元素引用

数组名[下标]

(4)字符数组的输入、输出

C对于字符串(双引号括起来的若干个字符),自动追加\0代表字符串结束标志,所有的字符串一定放在字符数组中存放

1) 逐个字符输入、输出 %c
2) 以字符串的形式一次输入、输出 %s

例如
char ch[10];
scanf(“%c”,&ch[0]);//%c逐个输入
scanf(“%s”,ch) //输入项为字符数组名,输入的字符串中不能包含空格(空格,回车,tab为字符串结束标志)
printf(“%c”,ch[0]);
printf(“%s”,ch);//输出字符串,一直到遇到第一个\0

(5)字符串处理函数

puts 输出字符串(\0结束的字符序列),将\0转换为换行,即输出字符串后换行------stdio.h
int puts(char * str)
puts(“strss”);

gets 输入一个字符串------stdio.h
char *gets(char *str); 输入一个字符串存放在str指向的内存中,同时返回这个地址

strcat---------字符串连接 string.h

Char * strcat(char *str1,char * str2 ) //str2连接到str1后面,返回str1
注意:str1指向的内存空间要足够大

strcpy -----字符串复制string.h

char * strcpy(char *str1,char *str2);//str2复制到str1,返回str1

Str1指向的空间应该足够大

char ch1[]=”hello”;
char ch2[];
ch2=ch1;//错误

Char * Strncpy(char *str1,char *str2,int n);//将str2前n个字符复制到str1

strcmp-----字符串比较函数 string.h
Strlen----字符串长度
Strlwr------转换为小写 char *strlwr(char *s)
Strupr------转换为大写

五、函数 (function)—完成一定功能的模块(算法),实现代码的复用

1、 函数的定义--------- 不可以嵌套定义,可以嵌套调用

1)函数的分类 库函数----自定义函数
从函数的形式分,分为有参函数和无参函数

2)函数的定义:分为函数首部(函数头),函数体两部分
语法:
返回值类型(函数类型) 函数名(形参表列)--------函数首部
{
说明部分(变量定义或函数声明) --------函数体
执行部分(语句)
}

注意:
返回值类型(函数的输出)的确定,首先判断函数是否需要返回一个值,如果需要再看返回值的类型,如果没有返回值,则明确声明为void,一定注意,返回值只能有一个,如果多于一个,只能通过别的方式带回,此时也将函数返回值类型声明为void

函数名:一个合法的标识符,尽量见名知意,多个单词连用,通常除了第一个单词外,其余单词首字母大写

形参表列:形参1类型 形参1名,形参2类型 形参2….,一个函数可以有多个形参,形参之间用逗号隔开,形参名是任意合法的标识符。是函数完成其功能时,所需要的必要的已知条件,相当于函数的输入,如果函数不需要已知条件,则空着,此时是无参函数。

函数体,是函数功能的具体实现(算法的具体实现),此时形参相当于已经有值(在函数调用时,由实参传递过来的值),不需要重新赋值,如果函数需要返回一个值,用return 语句带回(return语句将后面表达式的值带回到函数调用处,并结束函数的调用,return后面可以不加表达式,此时仅仅结束函数的调用,return语句可以有多个,但只有一个会执行)

例如:

1、 求两个数的和

double add(double x,double y)
{
    
    
    return x+y;
 }

2、 求两个整数的最大值

int max(int x,int y)
{
    
    
   return (x>y)?x:y;
}

3、 求1-100的和

int sum()
{
    
    
  int s=0,i;
for(i=1;i<=100;i++)
  s+=i;
return s;
 
}

4、 求两个整数的最大公约数

int fun(int x,int y)
{
    
    
}

5、 求两个整数的最小公倍数

int fun2(int x,int y)
{
    
    
}

6、判断一个数是否是素数

int isSushu(int x)
{
    
    
}

2、函数的调用

语法:
函数名(实参表列)

注意:
实参表列,实参可以是常量,变量或表达式。要求实参的个数和形参一致,类型和形参赋值兼容(形参1=实参1),实参必须有确定的值 i

如果要使用函数的返回值,可以定义一个和函数返回值类型一致的变量,接收返回值

案例,调用上面写的函数

1、 double s=add(3.5,5.6);//用常量做实参

或者
double x=3.5,y=5.6;
double s=add(x,y);//注意x,y是变量做实参,但x,y已经有确定的值
add(x+y,xy)//表达式做实参,求x+y和xy的和
add(a,add(a,b))add(a,b)&&1

注意:

1、 在发生函数调用时,首先程序执行的流程转到被调用函数,会给被调用函数的局部变量(定义在函数内部的变量,包括形参)分配内存空间,会将实参的值对应地传给形参

2、 在函数调用结束时(return语句或遇到函数体结束的右括号),程序执行的流程转到主调函数中函数调用处,回收被调用函数的局部变量(定义在函数内部的变量,包括形参)所占内存空间,如果需要return返回1个值,则把这个值带回函数调用处
因此,除了main函数外,其他函数中的局部变量只在被调用期间占有内存空间,不同函数的局部变量可以重名,仅仅是重名,一定占用不同的内存空间

3、函数调用时的参数传递

(1)普通变量(包括数组元素)做函数参数 由实参将值对应地传递给形参,传值调用(形参的改变不会影响实参)

(2)数组名做函数参数,由实参将值(地址)对应地传递给形参(传址调用)数组名就相当于一个指针

案例,函数完成数组排序:
void sort(int a[4]) ===》 void sort(int a[]) ====》 void sort(int *a)

如果指针指向数组,则指针变量可以带下标,此时指针变量相当于数组名

 {
    
    
        int i,j,t;
        for(j=10;j>1;j--)
            for(i=0;i<j-1;i++)
            {
    
    
                if(a[i]>a[i+1])
                {
    
    
                    t=a[i];
                    a[i]=a[i+1];
                    a[i+1]=t;
                }
            }
    }

4、函数的声明

编译系统自上而下编译代码,首先检查语法问题,没有问题则生成.obj文件,如果没有进行函数声明,编译系统自动地认为函数的类型(返回值的类型)是int型

以下代码中,f函数的类型为void,并且写在主调函数后,运行时报错,type mismatch in redeclaration of ‘f’,因此如果被调用函数如果写在主调函数后,且函数类型不是int,则必须添加函数声明

例如以下代码,在主调函数中并没有对被调用函数进行声明,程序可以正常执行,但此时存在风险 ,将下面红色字体的代码变成printf(“%d”,max3(x,y));时程序不报错,但运行结果不对,如果有函数声明,则此时红色字体的代码变成printf(“%d”,max3(x,y));时程序会报错 too few parameters in call to max3 in function main

函数声明(函数原型声明):
当被调用函数写在主调函数之后,此时可以在主调函数中,对被调用函数进行声明,方便编译系统检查函数调用表达式的正确性(检查项包括函数的类型、函数名字、参数的类型和个数)。

如果被调用函数写在主调函数之前,此时函数声明可以省略。

函数声明的语法: 函数返回值类型 函数名(形参1的类型,…);
或者函数返回值类型 函数名(形参1的类型 形参1,形参2类型 形参2);

猜你喜欢

转载自blog.csdn.net/qq_45696288/article/details/122069442