c语言
变量声明 定义 初始化
- 变量声明:对变量进行类型说明
- 定义性声明:分配内存空间,简称定义
- 引用性声明:extern引用其他的变量,不再额外分配内存空间,简称声明
- 变量 定义 初始化:为变量赋值,分配内存空间
变量作用域
每个变量和函数有两个属性:类型和存储类别。存储类别分静态存储区和动态存储区
-
静态存储区
全局变量存放的位置
//static时静态外部变量,只能用于本文件,不能被延伸到其他文件 for (int i=1;i<3;++i){ static int a=3; a++; }//a的值为6,当循环再一次执行static语句赋初值时会忽略,因为静态存储区只赋初值一次 //extern,其实是将其他地方的变量作用于延伸到extern处 //file1.c文件有int a;变量 //在file2/c文件若公用file1.c文件里a,则按下面方式声明即可 extern a;
-
动态存储区
局部变量存放的位置,如果局部变量加上static声明后,就会变为静态存储区,执行期间不被释放。
流程图
练习流程图 N-S图
输入输出
都不属于关键字,属于库函数
-
scanf,对多个变量进行输入
scanf("%d%d%d",a,b,c) //整型,用空格隔开
-
printf()
printf("%m.nf"); //m代表整个输出字符的宽度,n代表小数精确到n位。剩余列空间用空格在左端补上,若指定宽度小于实际宽度,则按实际宽度输出
运算符
- % :取余
- /:除号,用来做运算的,10/5=2
数据类型及运算
-
浮点型
- float型(单精度):单精度浮点数用4字节存储,可精确到小数点七位
- double型(双精度):双精度浮点数用8字节存储
-
浮点型 分母型
需要用float或者double型,常量与浮点型相乘除时候,常量也要加小数点
-
保留三位小数点
printf("%.3f",0.56789)
-
-
void 空类型
是指向空类型或者不指向确定的类型的数据,并非是能指向任何类型的数据 p287页
//如需指向
-
字符型与整型=整型(通过ASCII码)
-
运算
int i=1,j=5; int c=i+(++j); //c为7 c=i+++j //c为6
-
赋值
int c=i=j; // 先将j的值赋给i,然后i的值赋给c
-
左值与右值
//在赋值运算符左边的是左值,右边的是右值 int a = (b=3*4) //a的结果为3*4 int a = (a=b) = 3*4 //此表达式错误,因为(a=b)相对于3*4是左值,但(a=b)要么是1要么是0.不符合左值的要求
-
-
算数符 关系符 赋值符
-
优先级
算数》关系》赋值
a>b==c 等价于 (a>b)==c
- !(非)》算术》关系》&& || 》赋值
5>3 && 8<4-!0 5>3 && 8<(4-!0) //等价,结果都是0
-
如果一个表达式中的两个操作数具有相同的优先级 则用结合律
算术运算符和操作数的组合方式是从左到右,赋值运算符则是从右到左
*p1++ 等价于 *(p1++) 作用是先取出p1的值,然后p1++ *++p1 等价于 *(++p1) 作用是p1先自加1,然后取出p1的值
-
关系表达式和逻辑表达式的值都为0或1
-
数组
数组名只代表数组的首元素的地址
-
字符数组与字符串指针
//指针变量的值是可以改变的,而数组名代表一个固定的值,不可改变 //使用字符数组时,只能采用在定义数组时初始化或逐个对元素赋值的方法 char str[100]; char str[]={};//只能通过下标再对它进行赋值 char *string; string="dsa";//string指针指向字符串的首地址元素 string[1]=='s';//但不可改变其值 //只能用地址加减法访问,不能自增自减,如 printf("%s",str+2);//合法(str是数组名) str=str+1 //不合法
字符数组处理
//puts函数
char str[]={"hello"};
puts(str);
//gets函数
char str[10];
get(str);
char str[]={"sunzhijian"};
str[11]='d';
puts(str);//结果为sunzhijian,第十位是' ',puts发现 后就结束输出
char str[]={"sunzhijian"};
str[10]='d';
str[11]='d';
puts(str);//结果为sunzhijiandd
//二维数组定义时 第二个下标必须声明
字符数组的库函数操作
先include<string.h>
//比较
strcmp(str1,str2)//相同则0,以第一个不相同的字母比较结果为准,str1》2则返回1,str《str2返回-1
//连接
strcat(str1,str2);//将str2连接到str1上去,且返回str1
//赋值
strcpy(str1,str2);//将str2按下标赋值到str1上去
strncpy(str1,str2,n);//将str2中前n个字符赋值到str1前n位上去
//实际长度
strlen(str);//等价于遍历到str[i]==' ';
//字符数组的大小写转换
strlwr(str)//将字符串大写转小写
strupr(str)//将字符串小写转大写
指针
要区别指针和指针变量,指针就是地址本身,就是一个具体的地址值,而指针变量是用来存放地址的变量。所以认为指针是类型名是错误的,类型是没有值的,只有变量才有其值。
指针变量的值是所指向变量的内存地址,在指针变量上加*代表指针所指向变量。通过※point_a可以对变量a进行操作。
-
一个指针包含:存储单元编号的地址;它指向的存储单元的数据类型
-
由于数据在内存中所占的字节数和存储方式的不同,指针必须指定基类型
-
指针变量只能赋值内存地址,不能直接赋值整型。但可以把指针指向到一个整型数
*point_a == a;//二者是等价的
point_a == &a;//二者是等价的
- 实参与形参的数据传递是“值传递”的方式,传递的只是单纯的数值.
数组指针
-
指针可以指向数组中的每一个元素
int *p1,*p2; int list[]={1,2,3,4}; p1=&list[1],p2=&list[2]; //p2-p1等于1 p1+1等于list[2];//加的是数组元素所占的字节数,不是单纯的1,并且数组元素在内存中地址是连续的 p++//数组指针p加一个存储单元的长度
指针数组
int *p[4];//因为[]优先级高于*,所有p先与[]组合,成为一个包含四个元素的数组,而int * 声明数组中的元素都是int型指针类型的
int (*p)[4];//p声明为一个指针变量,指向包含四个整型元素的一维数组
多维数组指针
若a是一个二维数组,则其性质为
-
[] 优先级高于 *
-
获取二维数组的某个元素使用两次※或者 [] ,二个符号可任意组合
-
a+i是个行指针,即指向的是一整行(某行的整块),而不是单个元素,对它加一则代表指向下一行
-
a[i]代表a的第i行首地址,即&a【i】[0]
a是二维数组名,从二维角度进行操作 //a+i是个行指针,即指向的是一整行(某行的整块),而不是单个元素,对它加一则代表指向下一行 a[i]是一位数组名,从一维角度进行操作 //a[i]+1 则是从第i行第二个元素 //参考 p256 图8.20
-
*(a+1)[2],代表从第二行往下再加两行得到的首地址元素
-
二维数组
//二维数组参数 void func(int a[][3]); int array[][3]={{1,2}}; func(a);//因为传递的是内存地址,若在func中改变a的值,则array的值业随之改变
-
二维数组指针
int (*p)[3]; //指向一维数组(包含四个元素)的指针 void output( int (*p)[3]){p[1][1]} //可以传入一个n行三列的数组 //p[1][2]第二个数组的指针的第三个下标
函数指针
指向函数的指针
程序中定义了一个函数,编译时,会为其分配一段存储空间,存储空间的起始地址称为函数的指针
int (*p)(int,int);//p是指向函数的指针,且函数参数为两个整型,返回值为int型
int (*p)(int,int);//定义函数指针
p=max;//指针指向函数,不能将形参给出,否则就是把函数执行后的返回值给p了
(*p)(a,b);//屌用函数
函数类型为指针的函数
函数类型为指针的函数也就是定义一个返回值为指针的函数
int *p(int,int){}//()优先级高于*
//p先与()结合成函数,然后*声明为int指针类型
动态分配内存
需要头文件 # include <stdlib.h>
-
malloc函数
void *malloc(unsigned int size); void *calloc(unsigned n,unsigned size); void free(void *p); void *realloc(void *p,unsigned int size);
结构体
-
定义
有两种定义方式:typedef struct 和struct
struct 结构体名{ }变量名; struct Stu{ }; struct Stu stu1;//声明结构体变量stu1,需要指明Stu是个结构体类型 typedef struct 结构名{ }结构体别名;//结构体别名只是名称,不是具体的变量 typedef struct Stu{//typedef 的作用告诉系统Stu是个结构体类型名 }; //声明结构体变量 Stu stu1;
typedef struct Node{ }Node,*Nodep;//给结构体起别名Node,此结构体指针类名为Nodep Node node1; Nodep *p; struct Node{ }node,*p;//声明一个node结构体变量,和一个p结构体指针
原码 补码 反码
-
补码
-
正数的原码等于补码
-
负数的补码等于原码的数字位取反,末位加一
-
库函数
math
- sqrt(number) :求number的平方根
- fabs(double number):求number的绝对值
经典算法
- 模块化
- 数据类型
- 一维数组
- 二维数组
- 链表
- 公式
- 记住经典算法
判断素数(1-100内)
-
判断素数函数模块
- 如果传入是素数,return 1;否则return 0;
反向求解
-
如果i不能被2~i-1的数整除,则是素数
//判断素数模块
int isPrim(int x){
int i;
//从2开始
for(i=2;i<x;i++)
if (x%i==0)
return 0;
return 1;
}
//装素数
void fun(int a[]){
int i,index=0;
for(i=2;i<=100;i++)
if(isPrim(i))
a[k++]=i;
}
闰年
-
分析条件
能被4整除且不能被100整除
可被400整除
-
code
(year%4==0&& year%100!=0 || year % 400 ==0)