学习笔记,小白可以相互学习,大佬看到能告诉咱理解不对的地方就好了。
仅仅用来提醒自己那些需要注意的,自己没记好的;
计算机:
哈佛结构,哈佛结构是一种将程序指令存储和数据存储分开的存储器结构
冯诺依曼结构,是一种将程序指令存储和数据存储合并在一起的存储器结构
C语言
流程: 编辑 ---- 编译、链接 ----- 执行vim gcc a.out // gcc test.c -o test
构成
32个关键字:存储类型: auto const extern register volatile static signed unsigned
数据类型: char short int long float double
控制语句: if else switch case default for do while goto
continue break return
空类型: void
构造类型: enum union struct
求字节大小: sizeof
取别名: typedef
标识符 程序员自己命的名字
运算符:算术运算符:关系运算符:逻辑运算符:位运算符:赋值运算符:三目运算符:
控制语句:顺序语句,分支,循环
标点符号: , ---> 间隔 ; ---> 代表一个语句的结束
ASCII码表
字符表 用单引号括起来'a' --- 97,'A' --- 65,'0' --- 48,'\0' --- 0 //空字符' ' --- 32,'\n' --- 10
// 数字和数字字符之间的转换!//大小写转换
//字符比较 ---> 比较的是ASCII码值
/ ---- 转义字符
计算机 最小的存储单位 --- 字节 byte ,1个字节 = 8位
计算机存储:
二进制: 0 1 满2进制,十进制: 0 1 2 3 4 5 6 7 8 9 满10进1,八进制: 0 1 2 3 4 5 6 7,十六进制: 0 1 2 3 4 5 6 7 8 9 a b c d e f // 0x
数据类型
signed: 有符号 (如果不写,默认都是有符号的)// 有符号数最高位 表示符号位!!! 0--->正数 1---->负数
unsigned: 无符号char :
字符类型 -----> 属于整型
1个字节 8位 --> 0000 0000 ~ 1111 1111 ---> 0 ~ 2^8 - 1 ---> 0 ~ 255signed : 0 000 0000~0 111 1111 ----> 0 ~ 2^7 - 1 (0~127)
1 000 0000~1 111 1111 ----> -128 ~ -1 (-2^7 ~ -1)
//存储过程中,正数,转换为2进制,原样存储(原码存储)
// 负数存储 --> 按补码的方式存储
补码 == 原码 按位 取反 + 1
unsigned: 0 ~ 2^8 - 1
short : 短整型
2个字节 16位 --> 0000 0000 0000 0000 ~ 1111 1111 1111 1111 --> 0 ~ 2^16-1signed : 0 ~ 2^15-1 -2^15 ~ -1
// (-2^15 ~ 2^15-1)
unsigned:0 ~ 2^16-1
int :
4个字节 32位 --> 0 ~ 2^32 -1signed : (-2^31) ~ (2^31-1)
unsigned: 0 ~ 2^32 -1
long: 长整型
4个字节 32位 --> 0 ~ 2^32 -1signed : (-2^31) ~ (2^31-1)
unsigned:0 ~ 2^32 -1
float
4个字节 32位1位符号位
8位指数位
23位小数位
精度: 5-6
double
8个字节 64位1位符号位
11位指数位
52位小数位
精度: 15-16
标识符
程序员自定义 的名字
规则:1、只能由 字母 数字 下划线组成
2、只能以 字母 下划线开头
3、不能与关键字相同
//严格区分大小写 Ab AB ab aB 四个不同的标识符
常量
//不会更改的
整型常量: 10 076 0x76 0b1010101 -2 -9浮点型常量: 1.23 3.14 -6.28 1234.5678 -0.001234
指数常量: 1.2345678e+3 -1.234e-3
字符常量: 'a' 'A' '0' ---> ASCII码表中的字符
字符串常量: 多个字符串在一起 "hello" "张三" "0288888"
标识常量: #define N 10
变量
<存储类型> <数据类型> <变量名>;每一个变量都有属于自己的存储空间 空间大小 由 数据类型决定
存储类型: auto const extern register volatile static
auto : 自动类型 (默认状态下就是自动类型)
自动在栈区中开辟 (数据类型)
register: 寄存器类型
在CPU上有很多很珍贵的寄存器(数量很少)
如果使用 register ,申请把这个变量放到寄存器中去
//不一定申请的到(不代表没有) 申请不到 会转化为自动类型
static : 静态类型
修饰全局变量 | 限定作用域,只用于当前文件 |
修饰局部变量 | 存储区发生改变,由栈区变为静态区 |
修饰函数 | 同上上 |
volatile: 防优化 //每一次读值,都会从内存中重新读取!
全局变量 (全局变量区) | 局部变量 (栈区) |
定义在所有模块外 | 定义在模块内部 |
适用范围: 整个文件中 用extern声明可用于 整个程序 | 适用范围: 当前模块
|
生命周期: 从定义开始到程序 结束 | 生命周期: 从定义到模块结束 |
4g虚拟内存图
4g | kernel | 内核 |
3g | 环境参数 | |
命令行参数 | main的参数 | |
栈区 | 操作系统自动 开辟或者释放 | |
mmp | 内存映射 | |
堆区 | 手动开辟释放 malloc,free | |
也叫全局 变量区 (静态区) | .bass .data | 未初始化全局变量 初始化全局变量 |
字符串常量区 | ||
0 | 代码段 |
运算符
算数运算符(浮点型不能取余%),关系运算符(0为假,非0为真),逻辑运算符(&&,!,||),位运算符(&与,|或,~取反,^异或,>>右移,<<左移)
printf修饰符
m | 输出数据域宽,数据长度<m,左补齐空格 |
.n | 对实数,指定的小数点后位数(四舍五入) 对字符串,指定实际输出位数 |
- | 输出数据左对齐(缺省是右对齐的) |
+ | 指定在有符号数的整数前面显示正号(+) |
0 | 输出数值是指定左面不使用的空位置自动填0 |
# | 在8,16进制数前面显示前到0,0x |
l | 在d,o,x,u前,指定输出精度为long型 |
l | 在e,f,g前,指定输出精度为double型 |
scanf:
*抑制符:指定输入项读入后不赋值给变量,例如scanf(“%*c%c”,&a);
ch = getchar()可用来清除输入的换行
scanf(“ %c”,&a);%前面有一个空格可以用来滤除所有的空白字符
指针:
*解引用,&取地址符,这2个互为逆运算
const int a;int const a;表示a不可更改(常量化)
const int *p=&a;不可更改*p,但是可更改a和p//可以修改原来的值,也可以修改指针变量里存放的地址,但是不能通过间接访问去改变原来的值
int const *p=&a;同上
int * const p=&a;p不可更改
指针变量:int *p=&a;p就是指针变量,类型为int *;指针变量中装的是地址,大小是固定的32位系统中是4个字节
指针数组:(本质是数组)
int *n【10】={&a,&b,&c……};n有10个元素,每个元素都是一个指针(这个指针是指向一个整型数组的)
数组指针:(本质是指针)
int (*p)【10】=&a;指向一整个数组的指针,这个数组有10个元素,每个元素都是int类型,数组首地址是a
二维数组指针:
(*p)[i] = *((*p)+i);p[i][j] = *((*p)+i+j)
函数
特点:1.功能的封装(重复利用,模块化)
2.函数在使用之前必须声明
3.main和普通函数一样,没有任何差别
4.头文件基本上都是函数的声明或者全局数据
定义宏:
头文件格式:例如:maopao.h
#ifndef MAOPAO_H //如果没有H这个宏一般所有字母大写中间用_代替
#define MAOPAO_H //那么就定义这个宏
/*具体内容*/
#endif //表示结束
归纳分析:
1.一个表达式分析从标识符入手
2.分析:标识符左右两边找到可以结合的部分
3.从结合后整体的左边开始分析(*左结合)//*a[10] --->a[10]是一个有10个元素的数组--->每个元素都是一个指针
4.整个表达式(语句)--->把分析出来的去掉--->结合格式去看
//<数据类型><数组名>[元素个数]
//int * a [10]
5.看剩下部分代表什么,在通过相同的方法分析剩下的部分
1.[]--->数组
*--->指针
尾巴上看到()--->函数
2.结合格式分析的类型
//<数据类型><变量名>
//<数据类型><数组名>[元素个数]
//<数据类型>*<指针变量名>
//<数据类型><函数名>(参数列表)
//变量名,数组名,指针变量名,函数名都是程序员自己定义的标识符
//去掉标识符,就是整个标识符的类型
// int (*p[10])(int n)
*p[10]--->p[10]是一个有十个元素的数组,每个元素都是一个指针
用m取代p[10] --->int(*m)(int n)-->*m就是一个指针变量
int (int n)--->参数类型为int,返回值为int的一个函数--->m就只一个指向函数的指针
分析指针:
1.地址:地址的数据类型--->就是该数据元素的数据类型+*
2.指针变量的数据类型--->指向的数据元素类型+*
3.*--->解引用(后面必须跟地址)//指向后面的地址空间(取不取内容看左值还是右值)
4.* 和 &互为逆运算
//int a=10;int *p=&a;
a的类型为int ,p的类型为int *
&a的类型int *,&p的类型int **
*(&p)==p,*(int **)==int*
*(&a)==a,*(int*)==int
函数与指针
指针函数:
int *func(int n);//func是一个参数为int类型,返回值是int *类型的函数,func的类型为int * (int)
函数指针:
void func(int n);
void (*p)(int n) = &func;//定义一个指针指向一整个函数--->函数指针
void *p =NULL;
p = &func;//&func的类型为*(int *(int))
(*(int (*)(int ))p)(int n);//void(int n)强制转换p的类型与func一样
递归函数:
1.自己调用自己完成
1.自己调用自己完成
2.递归必须要有结束条件,找到跳出口
3.递归代码很简洁(但是不提倡,能不用就不用,耗费内存)
结构体:(4字节对齐,一般同类型的写在一起)
struct stu{
成员信息;
}
/***************求素数***********************************************/
#include<stdio.h>
int ss();
int main()
{
int p;
p=ss();
printf("******一共有素数%d个******\n",p);
return 0;
}
int ss()
{
int i,j;
int a = 0,k = 0;
for ( i = 101 ; i < 500 ; i++ )
{
for ( j = 2 ; (j < i); j++)
{
if(i%j == 0)
{
k =1;
}
}
if ( k == 0)
{
printf("%d\n",i);
a++;
}
k = 0;
}
return a;
}
/****************除法******************************************/
#include<stdio.h>
int my_div(float a,float b,float *s);
int main(void)
{
float c;
float a,b;
float k;
printf("请输入除数a:\n");
scanf("%f",&a);
printf("请输入被除数b:\n");
scanf("%f",&b);
if ( my_div(a,b,&k) )
{
printf("%3.2f\n",k);
}
else
{
printf("输入错误,被除数不能为零\n");
}
return 0;
}
int my_div(float a,float b,float *s)
{
const float c = 0.00001;
if ( b >= (-c) && b <= c )
{
return 0;
}
else
{
*s = a/b;
return 1;
}
}
/**************mystrcat**********实现函数strcat********************/
#include<stdio.h>
char *mystrcat(char *str1,char *str2);
int main()
{
char str1[128] = {0};
char str2[128] = {0};
printf("请输入第1个字符串\n");
gets(str1);
printf("请输入第2个字符串\n");
gets(str2);
// str3 = mystrcat(str1,str2);
puts(mystrcat(str1,str2));
return 0;
}
char *mystrcat(char *str1,char *str2)
{
int i=0,j=0,k=0;
static char str3[256] = {0};
for( ;str1[i] != '\0'; )
{
str3[k++] = str1[i++];
}
for(; str2[j] != '\0' ;)
{
str3[k++] = str2[j++];
}
str3[k++] = '\0';
return str3;
}
/*************mystrcmp*************************************************/
#include<stdio.h>
int mystrcmp(char *str1,char *str2);
int main()
{
char str1[128] = {0};
char str2[128] = {0};
printf("请输入第1个字符串\n");
gets(str1);
printf("请输入第2个字符串\n");
gets(str2);
printf("%d\n",mystrcmp(str1,str2));
return 0;
}
int mystrcmp(char *str1,char *str2)
{
int i=0,j=0,k=0;
while(1)
{
if ( str1[i] > str2[j])
{
i++;
j++;
return 1;
}
else
{
return 0;
}
}
}
/**********************mystrcpy***************************************/
#include<stdio.h>
char *mystrncpy(char *str1,char *str2);
int main()
{
int n;
char a[128] = {0};
char b[10] = {0};
gets(a);
gets(b);
char *p = NULL;
puts(mystrncpy(a,b));
puts(a);
return 0;
}
char *mystrncpy(char *str1,char *str2)
{
int i = 0,j = 0;
while ( str1[i++] )
{
if ( str2[j] == str[i])
{
while ( str2[j++] == str1[i++] && j<strlen[str2])
{
str1[i++] = str1[];
}
}
}
return str1;
}
/********************mystrncpy*******************************/
#include<stdio.h>
char *mystrncpy(char *str1,char *str2,int n);
int main()
{
char a[128] = {0};
char b[10] = {0};
gets(a);
char *p = NULL;
puts(mystrncpy(b,a,5));
puts(b);
return 0;
}
char *mystrncpy(char *str1,char *str2,int n)
{
int i = 0,j = 0;
while ( (str1[i++] = str2[j++]) && (j < n) );
return str1;
}
/***************mystrlen***************************************/
#include<stdio.h>
int mystrlen(char *a);
int main()
{
char a[128] = {0};
int b;
//printf("请输入要获取的字符串个数\n");
//scanf("%d",&b);
//printf("请输入字符串\n");
gets(a);
printf("mystrlen(a) = %d\n",mystrlen(a));
return 0;
}
int mystrlen(char *a)
{
int i = 0,j = 0;
while( a[i++] != '\0' )
{
j++;
}
return j;
}
/**********n个数移动m位依次替换**********************************/
#include<stdio.h>
int *move(int n,int m);
int main()
{
int n,m,i;int *b;;
printf("请输入数字个数:\n");
scanf("%d",&n);
printf("请输入移动位数:\n");
scanf("%d",&m);
b = move(n,m);
printf("****%d个数字移动%d位后****\n",n,m);
for(i = 0; i < n; i++)
{
printf("%d",b[i]);
}
puts("");
}
int *move(int n,int m)
{
int i,j;static int a[]={0};int b[m];int c[n-m];
printf("*********原来是**********\n");
for(i=0;i<n;i++)
{
a[i]=i;
printf("%d",a[i]);
}
puts("");
for(j=0;j<m;j++)
{
b[j] = a[n-m+j];
}
for(j=0;j<n-m;j++)
{
c[j]=a[j];
}
for(i=0;i<n;i++)
{
if(i<m)
{
a[i]=b[i];
}
else
{
a[i]=c[i-m];
}
}
return a;
}
/**********************删除特定字符串**************************************/
#include<stdio.h>
char *strdel(char *str1,char *str2);
int main()
{
//原字符串
char a[128] = {0};
gets(a);
//要删除的子串
char b[128] = {0};
gets(b);
puts(strdel(a,b));
puts(a);
return 0;
}
char *strdel(char *str1,char *str2)
{
int i = 0;
while(str1[i])
{
int j = 0;
if ( str1[i] == str2[j] )
{
int k = i;
while(str2[j])
{
if ( str1[k] == str2[j] )
{
k++;
j++;
}
else
{
break;
}
}
if ( str2[j] == '\0' )
{
while(str1[k])
{
str1[i] = str1[k];
k++;
i++;
}
str1[i] = '\0';
i = 0;
continue;
}
}
i++;
}
return str1;
}
/*****************删除特定字符***************************************/
#include<stdio.h>
char *strdel(char *str,char s);
int main()
{
char a[256] = {0};char b;
printf("请输入一个字符串:\n");
gets(a);
printf("请输入要删除的字符:\n");
scanf("%c",&b);
printf("删除后的字符串为:\n");
puts(strdel(a,b));
return 0;
}
char *strdel(char *str,char s)
{
int i=0,j;
while(str[i])
{
if(str[i] == s)
{
j = i;
while(str[j])
{
str[j] = str[j+1];
j++;
}
str[j++] = '\0';
//i = 0;
i--;
}
i++;
}
return str;
}
/***********************十进制转换成任意进制数**********************************/
#include<stdio.h>
#include<string.h>
int *zh(int a,int b);
int main()
{
int a,i,j;int b;
printf("请输入一个10进制数字:\n");
scanf("%d",&a);
printf("请输入要转换成几进制:\n");
scanf("%d",&b);
int *p = zh(a,b);
printf("转换%d进制的数字为:\n",b);
for(i = 1;i < p[0]; i++)
{
printf("%d",p[i]);
}
printf("\n");
return 0;
}
int *zh(int a,int b)
{
static int str1[1280];int d=1,j,i = 1,e=1;static int str2[1280];
for(i = 0; ; i++)
{
str1[i] = a % b;
a = a/b;
e++;
if (a == 0)
{
break;
}
}
for(j = i; j>= 0; j--)
{
str2[d++] = str1[j];
}
str2[0] = e;
return str2;
}
/*****************水仙花数************************************/
#include<stdio.h>
#include<stdlib.h>
int *sx(int low,int high);
int main()
{
int *p = sx(100,1000);
int i;
for(i = 1; i <= p[0] ; i++)
{
printf("%d\n",p[i]);
}
return 0;
}
int *sx(int low,int high)
{
static int buf[20];
int a,b,c,i;
int cnt = 1,st = 0;
for(i = low; i < high; i++)
{
a = i/100;
b = (i/10) %10;
c = i%10;
if( i == (a*a*a + b*b*b + c*c*c))
{
buf[cnt++] = i;
st++;
}
buf[0] = st;
}
return buf;
}
/***************************冒泡排序*******************************************/
#include<stdio.h>
int main()
{
int i,j,k;int a[10] = {0,2,9,5,6,1,3,8,7,4};
for ( i = 0; i < 9 ; i++ )
{
for ( j = 0 ; j < 9-i ; j++)
{
if (a[j] > a[j+1]) //先吧大数字往后面排
{
k = a[j];
a[j] = a[j+1];
a[j+1] = k;
}
}
}
for ( i = 0; i < 10 ; i++ )
{
printf("%d ",a[i]);
}
puts("");
return 0;
}
/***************************插入排序*******************************************/
#include<stdio.h> int main() { int i,j,k;int a[10] = {5,6,2,4,9,8,7,1,0,3}; for ( i = 1; i < 10 ; i++ )/*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/ { k = a[i];/*将待插入数暂存于变量t中*/ for ( j = i-1 ; (j > -1) && (a[j] > k); j--) // 前面的为一个部分,把后面的元素往前插入 { a[j+1] = a[j];/*若找到插入位置,则当前元素后移一个位置*/ } a[j+1]=k;/*未找到插入位置,不变*/ } for(i = 0; i < 10;i++) { printf("%d ",a[i]); } printf("\n"); return 0; }
#include<stdio.h> int main() { int i,j,k,min;int a[10] = {5,9,4,2,6,8,0,1,7,3}; for ( i = 0; i < 10 ; i++ ) { for ( j = i + 1 ; j < 10; j++) // 第i个数字与后面的所有比较,找出最小的排在第一个,然后找出第二小的... if ((a[j] < a[i])) { min = a[j]; a[j] = a[i]; a[i] = min; } } for(i = 0; i < 10; i++) { printf("%d ",a[i]); } printf("\n"); return 0; }