C语言复习
1、类型 运算符 语句
1.1、内存
X86 32位操作系统:地址->逻辑地址 4G
0x0000 0000~0xffff ffff
1G空间 内核态
3G空间 用户态(栈 堆 数据区 代码区 )
栈:从高地址向低地址位置开辟内存空间(先进后出)
堆:从低地址向高地址位置开辟空间
windows:数据内存 小端存储模式
int a=0x1234 5678 低地址向高地址存储(78 56 34 12)
1.指针验证
int a=0x12345678;
char *p=&a;
if(*p==0x78){
printf("小端存储模式");
}else{
printf("大端存储模式");
}
1.2、有符号数据类型,无符号类型
short ,int ,long,longlong 有符号数据类型,二进制符号位
signed short ,signed int,signed long……
无符号数据:
unsigned sort a=10;
unsigned int a=-10;
int main(){
unsigned char a=-10;//无符号1111 0110
printf("%d\n",a);//246
//%d有符号类型 %u 无符号类型
}
区间范围取值情况:
有符号:char:-128~127
无符号:char:0~255
1.3、进制
二进制->十进制
有符号类型:负数 补码=在原基础上按位取反+1
1101 0111 ->负->按位取反+1 1010 1001(原码)->计算结果:-41
0000 1010->正 计算结果:10
无符号类型:不存在负数 不存在符号位。所有位 数据位
1101 0111->直接计算结果:
0000 1010->计算结果:
十进制->二进制
正:辗转相除法
负数:-10 ->1.推算-10的原码1000 1010 2.按位取反加一 ->1111 0110补码
2、数组
2.1、一维数组
void Show(int *arr,int len){
for(int i=0;i<len;i++){
printf("%d",arr[i]);
}
}
int main(){
int arr[5]={1,2,3,4,5};
int len=sizeof(arr)/sizeof(arr[0]);
Show(arr,len);
}
数组名含义:数组起始地址 当数组的定义和sizeof(数组名)处与统一作用域,数组名此可代表整个数组大小
指针数组:const char* arr[2]={“hello”,“world”};
全局变量,字符串变量,静态全局变量->数据区
数组拷贝:
2.2、二维数组
二维数组数据存放是一维存储
二维数组:行:sizeof(crr)/sizeof(crr[0]);列:sizeof(crr[0])/sizeof(crr[0][0])
3.指针
3.1、一级指针
什么类型的变量用相同类型的指针指向它。
int a=10;//[0X1234]
int* p=&a;
*p=20;//a的值改为20,解引用 *p**p=20*20=400
//char* q=&a;
3.2、二级指针
int a=10;
int *p=&a;
int **q=&p;
3.3、指针与整型结合
int arr[10]={1,2,3,4,5,6,7,8,9,0};
int *p=arr;
//p+n的含义
//arr[n]<=>*(arr+n)<=>从arr位置偏移n*sizeof(arr[0])个字节大小的内存;
<=>*(p+n)<=>p[n]
//指针相减
int *p1=&arr[0];
int *p2=&arr[3];
p2-p1->减结果是将两个指针之间相差的单元个数。
两个指针必须指向统一块持续的内存空间,同一个数组。若指向不同区域,指针相减没有意义。
3.4、const和指针结合
const修饰的量为常变量(值不能被修改)
示例1
const int a=0;//a常变量 a=20;//error
//int *p=&a;//error
const int *p=&a;//right
示例2
int a=20;
int *p=&a;
const int* p=&a;//right
示例3:
int a=10,b=20;
int * const p=&a;//p为常变量,不能改变
p=&b;//error
*p=20;//right
示例4
//int *p,q;//p为int*,q为int类型
//int *p,*q;//p,q都为int*类型
/*
typedef:类型的重命名
typedef int * PINT;
PINT p,q;//p,q均为int*类型
*/
const int a=10,b=10;//a,b均为为常变量
const int *p=&a;//right
const int**q=&p;//right
int *const *s=&p;//error
int **const t=&p;//error
3.5、指针和数组
int arr[3];//01010101 01010101 01010101
memset(arr,0,sizeof(arr));//<string.h>
按字节初始化该内存
arr[1]=*(arr+1)
3.6、字符串和字符数粗
字符串和字符数粗关系:
const char *str="hello";
int len=strlen(str)->5字节;
sizeof(str)->4字节(X86);
//for(int i=0;i<len;i++){ }
while(*str!='\0'){
printf("%c",*str);
str++;
}
char arr[]="hello";//{'h','e','l','l','o'}
sizeof(arr);//6字节
strlen(arr);//5//统计字符个数,找到\0位置停止
char brr[]=123\0456;
sizeof(brr);//8字节
strlen(brr);//3字节
char crr[]={'h','e','l','l','o'};
sizeof(crr);//5
strlen(crr);//随机,找到后面随机数中存在\0停止
/*
字符串操作函数:
strlen()长度 strcat 链接 strcpy 拷贝 strcmp 比较
strn…… strchr 查找字符出现的位置 strstr主串中查找子串位置
字符串转整型 atoi函数实现
整型转字符串 itoa函数实现
*/
3.7、#include<string.h>
memset() 按字节初始化
memcpy()复制字符串
memove() 内存操作函数
4、递归
分支策略:
将大的问题规模分割为较小的问题规模。规模改变。
递归:栈->函数调用
1)函数自己调用自己 2)参数问题规模 3)退出条件
时间复杂度、空间复杂度:->非递归:计算(数据结构) 递归函数:递归深度有关
5、结构体、枚举、联合体
5.1、结构体
typedef struct BankCard{
int id;
int passwd;
}BankCard,*PCard;
BankCard b={1,1};
PCard p=&b;
p->id;//<=>(*p).id
b.id;
//结构体数组
BankCard cards[3]={{1.1},{2,2},{3,3}};
for(int i=0;i<3;i++){
cards[i].id=i;
}
5.2、枚举
typedef enum ChessKind{
black,white
}Kind;
//有赋值用赋值的数字,无赋值用前一个变量+1进行赋值
Kind k=black;//直接赋值
5.3、联合体(共用体)
联合体:成员共享同一个内存空间。内存大小取决于成员最大数据类型的字节数。
typedef union test{
int num;
char c;
};
int main(){
union test t={0x12345678};//只会先赋值给第一个成员,如果第一个是char c;
//就会发生数据截断,导致num的值为0x78检验大小端
if(t.c==0x78){
小端模式
}else{
大端模式
}
t.num;//0x78
};
typedef nuiom ID{
int stu_id;
int tea_id;
}ID;
typedef struct People{
const char* name;
int age;
ID id;
}People;
6、动态内存
6.1、malloc realloc calloc free
#include<stdlib.h>或#include<malloc.h>
//malloc(数组元素总字节数)
BankCard* arr=(BankCard*)malloc(10*sizeof(BankCard));//内存未初始化
assert(arr!=NULL);
//使用
free(arr);
arr=NULL;//防止出现野指针
//calloc(元素个数,每个元素占字节)
// 动态申请内存+初始化内存(类型默认值)->malloc+for
BankCard* arr=(BankCard*)calloc(10,sizeof(BankCard));//内存初始化
assert(arr!=NULL);
//使用
free(arr);
arr=NULL;//防止出现野指针
//realloc扩容(原内存的指针,新大小内存所占字节)
BankCard *p=(BankCard*)realloc(arr,20*sizeof(BankCard));
if(p==NULL){扩容失败}
arr=p;
//使用arr
free(arr);
arr=NULL;
free出现问题(崩溃):
1)重复释放同一段内存;
2)free操作一定是堆区间
3)移动指针首地址
7、文件操作
fopen fclose fread fwrite
FILE *fp1=fopen("路径 文件名.后缀","模式");
FILE *fp2=fopen("路径 文件名.后缀","模式");
assert(fp1!=NULL);
char buff[256];
int count=fread(buff,sizeof(char),256,fp1);//从fp1中读取256个字节数读buff中,
//存放从文件中读取的数据,每个元素字节数,元素个数,文件指针
//返回值:count 成功读取的元素个数
fwrite(buff,sizeof(char),count,fp2);//从fp2中读取count个字节数写入buff中,
fclose(fp1);
fclose(fp2);
模式:
字符串操作:
printf scanf
gets_s puts
getchar putchar
getc putc
sprintf sscanf
fgets(char *str,,stdin)<==>gets() fputs
fgetc fput