C语言函数与算法
ASCⅡ码
十进制 | 十六进制 | 字符 |
---|---|---|
9 | 9 | |
10 | A | |
32 | 20 | 空格 |
48 | 30 | 0 |
57 | 39 | 9 |
65 | 41 | A |
90 | 5A | Z |
97 | 61 | a |
122 | 7A | z |
常用函数
交换
void swap(int *a,int *b) {int temp=*a;*a=*b;*b=temp;}//记得传入的是指针
快速幂
int quickpow(int a,int b) //a的b次方
{
int r=1,base=a;
while(b!=0)
{
if(b&1) r*=base;
base*=base;
b>>=1;
}
return r;
}
全排列
int n,book[10],a[10];
void dfs(int x)//当前输入第x位
{
int i;
if(x==n+1)
{
for(i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
}
else
{
for(i=1;i<=n;i++)
{
if(book[i]==0)
{
a[x]=i;
book[i]=1;
dfs(x+1);
book[i]=0;
}
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
return 0;
}
蔡勒公式
计算哪年哪月哪日是星期几。
int Zeller(int y,int m,int d)//年、月、日
{
int w;
if(m<3) y--,m+=12;
int c=y/100;
if(y<1582||(y==1582&&m<10)||(y==1582&&m==10&&d<=4))
w=(y%100)+(y%100)/4+c/4-2*c+13*(m+1)/5+d+2;
else
w=(y%100)+(y%100)/4+c/4-2*c+13*(m+1)/5+d-1;
w=((w%7)+7)%7;
if(w==0) w=7;
return w;
}
逆波兰表达式
算式转为后缀表达式
struct Stack
{
int type;//type==0 digit type==1 signal
int num;//012345 +-*/()
} s[1005],n[1005];
int ps=0,pn=0;
int read(char c)
{
if(c=='+') return 0;
else if(c=='-') return 1;
else if(c=='*') return 2;
else if(c=='/') return 3;
else if(c=='(') return 4;
else if(c==')') return 5;
}
int main()
{
char tmp;
int t,ifnum=0,i;
while(scanf("%c",&tmp)!=EOF)
{
if(isdigit(tmp)&&ifnum==1)
{
t=t*10+tmp-'0';
}
else if(isdigit(tmp))
{
t=tmp-'0';
ifnum=1;
}
else
{
if(ifnum==1)//是数字,输出到n
{
pn++;
n[pn].type=0;
n[pn].num=t;
ifnum=0;
}
if(tmp=='(')//是(, 入栈s
{
ps++;
s[ps].type=1;
s[ps].num=5;
}
else if(tmp=='+'||tmp=='-'||tmp=='*'||tmp=='/')
{
while(1)
{
if(ps==0||(s[ps].type==1&&s[ps].num==5))//栈为空或栈顶为(,入栈
{
ps++;
s[ps].type=1;
s[ps].num=read(tmp);
break;
}
else if(s[1].type==1&&s[ps].num/2>=read(tmp)/2)//栈顶运算符优先级大,栈顶出栈到n
{
pn++;
n[pn]=s[ps];
ps--;
}
else//栈顶运算符优先级小,入栈
{
ps++;
s[ps].type=1;
s[ps].num=read(tmp);
break;
}
}
}
else if(tmp==')')//出栈,直到遇见(
{
while(!(s[ps].type==1&&s[ps].num==5))
{
pn++;
n[pn]=s[ps];
ps--;
}
ps--;// (出栈
}
else if(tmp=='=')//都出栈
{
while(ps>0)
{
pn++;
n[pn]=s[ps];
ps--;
}
break;
}
}
}
for(i=1; i<=pn; i++)
{
if(n[i].type==0) printf("%d",n[i].num);
else
{
switch(n[i].num)
{
case 0:
printf("+");
break;
case 1:
printf("-");
break;
case 2:
printf("*");
break;
case 3:
printf("/");
break;
}
}
}
return 0;
}
数学类
最小公约数
int gcd(int a,int b) {return a%b==0?b:gcd(b,a%b);}
判断质数
bool isprime(int x)
{
int tmp=floor(sqrt(x)+0.5);
for(int i=2;i<=tmp;i++)
if(x%i==0) return 0;
return 1;
}
生成质数表
int v[MAX_N],prime[MAX_N],m;//v[]存一个数最小质因子
void primes(int n)
{
memset(v,0,sizeof(v));
m=0;
for(int i=2;i<=n;i++)
{
if(v[i]==0)//i是质数
{
v[i]=i;
prime[++m]=i;
}
//给当前的数i乘上一个质因子
for(int j=1;j<=m;j++)
{
if(prime[j]>v[i]||prime[j]>n/i) break; //i有比prime[j]更小的质因子,或者超出n的范围
v[i*prime[j]]=prime[j]; //prime[j]是合数i*prime[j]的最小质因子
}
}
for(int i=1;i<=m;i++) printf("%d ",prime[i]);
}
求逆元
void exgcd(long long a,long long b,long long& d,long long &x,long long &y)
{
if(!b) {d=a;x=1;y=0;}
else{exgcd(b,a%b,d,y,x);y-=x*(a/b);}
}
long long inv(long long a, long long p)//a是要求逆元的数,p是模数
{
long long d,x,y;
exgcd(a,p,d,x,y);
return d==1?(x+p)%p:-1;
}
矩阵
矩阵乘法
//n×m矩阵*m×p矩阵
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=p;k++)
c[i][k]+=a[i][j]*b[j][k];
矩阵乘法求斐波那契数列第n项
#define N 2
//(f[i] ) (1 1) (f[i-1])
//(f[i-1])=(1 0)*(f[i-2])
struct node
{
long long g[N+1][N+1];
}f,res;
long long n,p;
void matrixmultiply(node &x,node &y,node &z)//z=x+y
{
memset(z.g,0,sizeof(z.g));
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
if(x.g[i][j])
{
for(int k=1;k<=N;k++)
{
z.g[i][k]+=x.g[i][j]*y.g[j][k];
z.g[i][k]%=p;
}
}
}
}
void matrixquickpow(int k)//矩阵快速幂
{
node tmp=f,t;
while(k)
{
if(k&1) {matrixmultiply(res,tmp,t);res=t;}
matrixmultiply(tmp,tmp,t);tmp=t;
k>>=1;
}
}
long long solve()
{
if(n<=2) return 1;
matrixquickpow(n-2);//算前面系数矩阵的n-2次方
long long ret=res.g[1][1]+res.g[2][1];//求f[i]
ret%=p;
return ret;
}
int main()
{
scanf("%lld%lld",&n,&p);//第n个数,模p
//系数矩阵
f.g[1][1]=1;
f.g[1][2]=1;
f.g[2][1]=1;
f.g[2][2]=0;
//构造单位矩阵
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i==j) res.g[i][j]=1;
else res.g[i][j]=0;
long long ans=solve();
printf("%lld",ans);
return 0;
}
求矩阵的秩(高斯-若尔当消元法)
int t,n,m,i,j,k,tmp,rank,x;
double a[maxn][maxn],b[maxn][maxn],Tmp;
scanf("%d%d",&n,&m);
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
scanf("%lf",&a[i][j]);
if(n<m)//如果n<m将矩阵转置
{
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
b[j][i]=a[i][j];
tmp=n,n=m,m=tmp;
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
a[i][j]=b[i][j];
}
rank=0;
for(i=1; i<=m; i++)
{
//将所有行该列中绝对值最大的那个元素所在的行交换到第i行以减少浮点误差
x=i;
for(j=i+1; j<=n; j++)
if(fabs(a[j][i])>fabs(a[x][i]))
x=j;
if(fabs(a[x][i])<1e-2) continue;//该列全为0,跳过
rank++;
if(x!=i)
for(j=1; j<=m; j++)
Tmp=a[i][j],a[i][j]=a[x][j],a[x][j]=Tmp;
for(j=1; j<=m; j++)
if(i^j)a[i][j]/=a[i][i];
a[i][i]=1;
for(j=1; j<=n; j++)
{
if(j==i) continue;
for(k=1; k<=m; k++)
{
if(k==i) continue;
a[j][k]-=a[j][i]*a[i][k];
}
a[j][i]=0;
}
}
printf("%d",rank);
高精度
字符数组转整型数组
void array_char_to_int(char a[],int b[])
{
int len=(int)strlen(a);
for(int i=0;i<len;i++) b[len-i]=a[i]-'0';
}
高精加高精
void add_HH(int a[],int b[]) //记得为lena,lenb赋值
{
int x=0;//进位
lenc=1;
while(lenc<=lena||lenc<=lenb)
{
c[lenc]=a[lenc]+b[lenc]+x;
x=c[lenc]/10;
c[lenc]%=10;
lenc++;
}
c[lenc]=x;
if(c[lenc]==0) lenc--;//处理最高位
}
高精加低精
void add_HL(int a[],int b)
{
int x=0,t,i;//t为低精度当前位
for(i=1;i<=lena||b>0;i++)
{
t=b%10;
b/=10;
c[i]=a[i]+t+x;
x=c[i]/10;
c[i]%=10;
}
lenc=i-1;
}
高精减高精
void subtract_HH(int a[],int b[])
{
int i=1;
while(i<=lena||i<=lenb)
{
if(a[i]<b[i])
{
a[i]+=10;
a[i+1]--;
}
c[i]=a[i]-b[i];
i++;
}
lenc=i;
while((c[lenc]==0)&&(lenc>1)) lenc--;//去除高位的0
}
判断是否为小数减大数
void subtract_cmp(char a[],char b[])
{
if(strlen(a)<strlen(b)||(strlen(a)==strlen(b)&&strcmp(a,b)<0))
{
strcpy(temp,a);//将a复制给temp,temp是中间数组
strcpy(a,b);
strcpy(b,temp);
printf("-");
}
}
高精乘高精
void multiply_HH(int a[],int b[])
{
int x;//进位
for(int i=1;i<=lena;i++)
{
x=0;
for(int j=1;j<=lenb;j++)
{
c[i+j-1]=a[i]*b[j]+x+c[i+j-1];//当前乘积+上次乘积进位+原数
x=c[i+j-1]/10;
c[i+j-1]%=10;
}
c[i+lenb]=x;
}
lenc=lena+lenb;
while(c[lenc]==0&&lenc>1) lenc--;//删除前导0
}
高精乘低精
void multiply_HL(int a[],int b)
{
int t,x;//进位
for(int i=1;i<=lena;i++)
{
int j;
x=0;t=b;
for(j=1;t;j++)
{
c[i+j-1]=a[i]*(t%10)+x+c[i+j-1];//当前乘积+上次乘积进位+原数
x=c[i+j-1]/10;
c[i+j-1]%=10;
t/=10;
}
lenb=j-1;
c[i+lenb]=x;
}
lenc=lena+lenb;
while(c[lenc]==0&&lenc>1) lenc--;//删除前导0
}
高精除以高精
char a1[1005],b1[1005];
int a[1005],b[1005],c[1005];
//a[0],b[0]存长度
void array_char_to_int(char a[],int b[])
{
int len=(int)strlen(a);
for(int i=0;i<len;i++) b[len-i]=a[i]-'0';
}
int compare(int a[],int b[])//比较a[],b[]大小,a>b返回1
{
int i;
if(a[0]>b[0]) return 1;
if(a[0]<b[0]) return -1;
for(i=a[0];i>0;i--)//从高位到低位比较
{
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return -1;
}
return 0;
}
void subtract(int a[],int b[])//a=a-b
{
int flag=compare(a,b);
if(flag==0) {a[0]=0;return;}
else if(flag==1)
{
for(int i=1;i<=a[0];i++)
{
if(a[i]<b[i])
{
a[i+1]--;
a[i]+=10;
}
a[i]-=b[i];
}
while(a[0]>0&&a[a[0]]==0) a[0]--;//去0
return;
}
}
void numcpy(int a[],int b[],int det)//复制a[]到b[]从det开始的地方
{
for(int i=1;i<=a[0];i++) b[i+det-1]=a[i];
b[0]=a[0]+det-1;
}
void divide_HH(int a[],int b[],int c[])
{
int i,tmp[1005];
c[0]=a[0]-b[0]+1;
for(i=c[0];i>0;i--)
{
memset(tmp,0,sizeof(tmp));
numcpy(b,tmp,i);
while(compare(a,tmp)>=0) {c[i]++;subtract(a,tmp);}
}
while(c[0]>0&&c[c[0]]==0) c[0]--;
return;
}
int main()
{
gets(a1);
gets(b1);
a[0]=(int)strlen(a1);
b[0]=(int)strlen(b1);
array_char_to_int(a1,a);
array_char_to_int(b1,b);
divide_HH(a,b,c);
for(int i=c[0];i>=1;i--) printf("%d",c[i]);//商
printf("\n");
for(int i=a[0];i>=1;i--) printf("%d",a[i]);//余数
return 0;
}
高精除以低精
void divide_HL(int a[],int b)
{
int x=0;
for(int i=lena;i>=1;i--)
{
c[i]=(x*10+a[i])/b;
x=(x*10+a[i])%b;
}
//x就是余数
lenc=lena;
while(c[lenc]==0&&lenc>1) lenc--;//删除前导0
}
y/x保留到小数点后len位
void divide_decimal(int y,int x,int len)
{
printf("%d",y/x);
y%=x;
if(y==0) return;
printf(".");
while(len--)
{
y*=10;
printf("%d",y/x);
y%=x;
if(y==0) return;
}
}
qsort和bsearch
int类型
int cmp_int(const void* _a,const void* _b) //参数格式固定,bsearch与qsort的函数一致
{
int* a=(int*)_a; //强制类型转换
int* b=(int*)_b;
return *a-*b; //升序
//return *b-*a; //降序
//(有时候范围会超int!!!)
}
qsort(ArrayName,size,sizeof(ArrayName[0]),cmp_int); //从0开始,一共排size个
int key;
//key是要找的数,要为key赋值;从0开始找,一共查找size个数
int *p=(int*)bsearch(&key,ArrayName,size,sizeof(int),cmp_int);
//若找到key,*p返回找到的数的值(即key);若未找到,返回空指针NULL;p-ArrayName可以算出下标值b
double类型
int cmp_double(const void* _a,const void* _b) //参数格式固定
{
double* a=(double*)_a; //强制类型转换
double* b=(double*)_b;
return *a>*b?1:-1; //升序
//return *a>*b?-1:1; //降序
}
qsort(ArrayName,size,sizeof(ArrayName[0]),cmp_double);
char类型
int cmp_char(const void* _a,const void* _b) //参数格式固定
{
char* a=(char*)_a; //强制类型转换
char* b=(char*)_b;
return *a-*b; //升序
//return *b-*a; //降序
}
qsort(ArrayName,size,sizeof(ArrayName[0]),cmp_char); //从0开始,一共排size个
char[]类型
int cmp_string(const void* _a,const void* _b) //要定义二维字符数组
{
char* a=(char*)_a; //强制类型转换
char* b=(char*)_b;
return strcmp(a,b); //字典序
}
qsort(ArrayName,size,sizeof(ArrayName[0]),cmp_string);
struct类型
int cmp_struct(const void *_a ,const void *_b) //Note为结构体名
{
struct Note *a=(struct Note *)_a;
struct Note *b=(struct Note *)_b;
//return a->x-b->x; //升序
//return b->x-a->x; //降序
//双关键字排序
//if(a->x!=b->x) return a->x-b->x; //第一关键字升序
//else return b->y-a->y; //第二关键字降序
}
qsort(结构体变量名,size,sizeof(结构体变量名[0]),cmp_struct);
int key;
//key是要找的数,要为key赋值;从0开始找,一共查找size个数
Note *p=(Note*)bsearch(&key,StructName,size,sizeof(StructName[0]),cmp_struct);
//若找到key,*p返回找到的数的值(即key);若未找到,返回空指针NULL;p-StructName可以算出下标值
//如:StructName[p-StructName].element
快读快写
快读
inline int read()
{
int x=1,y=0;
char ch=getchar();
//为避免输入数字之前的空格造成影响
while(ch<'0'||ch>'9'){if(ch=='-') x=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){y=y*10+ch-'0';ch=getchar();}
return x*y;
}
快写
inline void write(int n)
{
if(n<0) putchar('-'),n*=-1;
if(n>9) write(n/10);
putchar(n%10+'0');
}
进制转换
char array[40]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
任意进制转十进制(低精)
//仅支持2~10进制转化为10进制
int todecimalism_L(int x,int p)//x:要转的数 p:进制数
{
int ans=0,w=1;
while(x!=0)
{
ans+=(x%10)*w;
x/=10;
w*=p;
}
return ans;
}
十进制转任意进制(低精)
void toanyradix_L(int x,int p)
{
if(x!=0)
{
toanyradix(x/p,p);
printf("%c",array[x%p]);
}
}
//注意特判0!!!
任意进制转任意进制(高精)
char a1[10005];
int a[10005],c[10005],lena,lenc,oldbase,newbase;
void array_char_to_int(char a[],int b[])
{
int len=(int)strlen(a);
for(int i=0;i<len;i++)
{
if(isdigit(a[i])) b[len-i]=a[i]-'0';
else if(isupper(a[i])) b[len-i]=a[i]-'A'+10;
}
}
int divide_HL(int a[],int oldbase,int newbase)
{
int x=0;
for(int i=lena;i>=1;i--)
{
c[i]=(x*oldbase+a[i])/newbase;
x=(x*oldbase+a[i])%newbase;
}
//x就是余数
lenc=lena;
while(c[lenc]==0&&lenc>1) lenc--;//删除前导0
memcpy(a,c,sizeof(c));
lena=lenc;
return x;
}
void anyradix_H(int a[],int oldbase,int newbase)
{
if(lena>=2||(lena==1&&a[1]!=0))
{
int x=divide_HL(a,oldbase,newbase);
anyradix_H(a,oldbase,newbase);
printf("%c",array[x]);
}
}
int main()
{
scanf("%s%d%d",a1,&oldbase,&newbase);
array_char_to_int(a1,a);
lena=(int)strlen(a1);
anyradix_H(a,oldbase,newbase);
}
深搜广搜
struct Note
{
int x;
int y;
}q[100001];
int startx,starty,endx,endy,N;
short next[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool result,book[105][105];
bool map[105][105];
void bfs(int m,int n)
{
int head=1,tail=1;
q[1].x=m,q[1].y=n;
tail++;
while(tail>head)
{
for(int i=0;i<=3;i++)
{
int nx=q[head].x+next[i][0];
int ny=q[head].y+next[i][1];
if(map[nx][ny]==0&&book[nx][ny]==0&&nx>=0&&nx<N&&ny>=0&&ny<N)
{
book[nx][ny]=1;
q[tail].x=nx;
q[tail].y=ny;
tail++;
if(nx==endx&&ny==endy)
{
result=1;
break;
}
}
}
if(result==1) break;
head++;
}
return;
}
void dfs(int x,int y)
{
if(result==1) return;
if(x==endx&&y==endy)
{
result=1;
return;
}
for(int i=0;i<=3;i++)
{
int nx=x+next[i][0];
int ny=y+next[i][1];
if(map[nx][ny]==0&&book[nx][ny]==0&&nx>=0&&nx<n&&ny>=0&&ny<n)
{
book[nx][ny]=1;
dfs(nx,ny);
}
}
return;
}
int main()
{
char c;
cin>>N;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
cin>>c;
if(c=='#') map[i][j]=1;//障碍
else map[i][j]=0;
}
cin>>startx>>starty>>endx>>endy;
result=0;
memset(book,0,sizeof(book));
book[startx][starty]=1;
dfs(startx,starty);
bfs(startx,starty);
if(result==0) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
return 0;
}
排序
冒泡排序
for(i=n-1;i>=1;i--)//对1~n排序
{
book=1;
for(j=1;j<=i;j++)
if(a[j]>a[j+1])
{
swap(&a[j],&a[j+1]);
book=0;
}
if(book==1) break;
}
快速排序
void quicksort(int left,int right)
{
int i,j,mid,temp;
i=left,j=right;
mid=a[(left+right)/2];//基准数
do
{
//升序
while(a[i]<mid) i++;
while(a[j]>mid) j--;
//降序
//while(a[i]>mid) i++;
//while(a[j]<mid) j--;
if(i<=j)
{
temp=a[i],a[i]=a[j],a[j]=temp;
i++,j--;
}
}while(i<=j);
if(left<j) quicksort(left,j);
if(i<right) quicksort(i,right);
}
归并排序
void msort(int s,int t)
{
if (s==t) return;
int mid=(s+t)/2;
msort(s,mid);
msort(mid+1,t);
int i=s,j=mid+1,k=s;
while(i<=mid&&j<=t)
{
if (a[i]<=a[j])
{
r[k]=a[i];
k++,i++;
}
else
{
r[k]=a[j];
k++,j++;
ans+=mid-i+1;//统计逆序对
}
}
while(i<=mid)
{
r[k]=a[i];
k++,i++;
}
while(j<=t)
{
r[k]=a[j];
k++,j++;
}
for (i = s; i <=t; i++) a[i]=r[i];
}
图论
并查集
int getf(int v)
{
if(f[v]==v) return v;
f[v]=getf(f[v]);
return f[v];
}
int merge(int u,int v)
{
int t1,t2;
t1=getf(u);
t2=getf(v);
if(t1!=t2)
{
f[t2]=t1;
return 1;//合并成功
}
return 0;//本来就是一个团伙,不用合并
}
最小生成树
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,tot=0,k=0;//n端点总数,m边数,tot记录最终答案,k已经连接了多少边
int fat[200010];//记录集体老大
struct node
{
int from,to,dis;//结构体储存边
}edge[200010];
bool cmp(const node &a,const node &b)//sort排序(当然你也可以快排)
{
return a.dis<b.dis;
}
int father(int x)//找集体老大,并查集的一部分
{
if(fat[x]!=x)
return father(fat[x]);
else return x;
}
void unionn(int x,int y)//加入团体,并查集的一部分
{
fat[father(y)]=father(x);
}
int main()
{
scanf("%d%d",&n,&m);//输入点数,边数
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].dis);//输入边的信息
}
for(int i=1;i<=n;i++) fat[i]=i;//自己最开始就是自己的老大 (初始化)
sort(edge+1,edge+1+m,cmp);//按权值排序(kruskal的体现)
for(int i=1;i<=m;i++)//从小到大遍历
{
if(k==n-1) break;//n个点需要n-1条边连接
if(father(edge[i].from)!=father(edge[i].to))//假如不在一个团体
{
unionn(edge[i].from,edge[i].to);//加入
tot+=edge[i].dis;//记录边权
k++;//已连接边数+1
}
}
printf("%d",tot);
return 0;
}
部分库、函数用法
sscanf
int sscanf(const char *str, const char *format, ...)
// 用法一:取指定长度的字符串
sscanf("12345","%4s",str); // 取字符的前4位 str:"1234"
// 用法二:格式化时间
sscanf("2013/02/13 14:55:34","%d/%d/%d %d:%d:%d",&year,&month,&day,&hour,&minute,&second);
// 用法三:读入字符串
sscanf("12345","%s",str);
// 用法四:%*d 和 %*s 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
sscanf("12345acc","%*d%s",str); // str:"acc"
sscanf("12345abc","%d%*s",&num); // num:12345
// 用法五:取到指定字符为止的字符串。如在下例中,取遇到'+'为止字符串。
sscanf("12345+acc","%[^+]",str);
// 用法六:取到指定字符集为止的字符串。
sscanf("eihbu","%[e-m]",str); // 取e-m之间的字符,若不是终止读入 str:"eih"
sscanf("bvccbuaa","%[b|c|v]",str); // 取b,c或v,若不是则中止 str:"bvccb"
sscanf("12345+acc","%[^+]",str); // 取遇到'+'为止的字符串 str:"12345"
sscanf("12345+acc121","%[^a-z]",str); // 取遇到小写字母为止的字符串 str:"12345+"
sscanf(c,"%5s-%*[a-f] %[A-D]_*%[s|d|l]",str1,str2,str3); //str1:"12345" str2:"ABCD" str3:"sd"
string.h
memset(intArray,num,sizeof(intArray))//赋值0:0 0x3f3f3f3f:无穷大(相加不会溢出) 127:无穷大 128:无穷小
char a[105],b[105];
int n;
char *p,c;
strcat(a,b); //将b追加到a后
strncat(a,b,n); //将b的前n位追加到a后
strcpy(a,b); //将b复制到a
strncpy(a,b,n); //将b的前n位复制到a
printf("%d",strncmp(a,b,n)); //比较a和b的前n位
puts(b);
p=strchr(a,c); //查找字符c在a中第一次出现的位置(p=a中第一个c的地址)
p=strrchr(a,c); //查找字符c在a中最后一次出现的位置(p=a中最后一个c的地址)
p=strstr(a,b); //查找子串b首次出现的位置(p=a中第一个子串b的第一个字符的地址)
//strchr例:
p=a;
while((p=strchr(p,c))!=NULL)
{
printf("%d ",p-a); //下标
p++;
}
//strstr例:
p=a;
while((p=strstr(p,b))!=NULL)
{
printf("%d ",p-a); //下标
p+=strlen(b);
}
atoi、atof
char a[105];int n;double f;
n=atoi(a);//将数字字符串转化为int类型(遇到非数字则中止)
f=atof(a);//将数字字符串转化为double类型(遇到非数字则中止(第一个小数点除外))
time.h
/*
clock_t clock( void ); 这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数。
clock_t是一个长整形数
系统常量:#define CLOCKS_PER_SEC 1000
struct tm
{
int tm_sec; 秒 – 取值区间为[0,59]
int tm_min; 分 - 取值区间为[0,59]
int tm_hour; 时 - 取值区间为[0,23]
int tm_mday; 一个月中的日期 - 取值区间为[1,31]
int tm_mon; 月份(从一月开始,0代表一月) - 取值区间为[0,11]
int tm_year; 年份,其值等于实际年份减去1900
int tm_wday; 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推
int tm_yday; 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推
int tm_isdst; 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。
};
time_t是一个长整型数。用time_t表示的时间(日历时间)是从一个时间点
(例如:1970年1月1日0时0分0秒)到此时的秒数。
将日历时间(一个用time_t表示的整数)转换为我们平时看到的把年月日时分秒分开显示的时间格式tm:
struct tm * gmtime(const time_t *timer);
struct tm * localtime(const time_t * timer);
我们可以通过time()函数来获得日历时间(Calendar Time),其原型为:
time_t time(time_t * timer);
我们可以通过asctime()函数和ctime()函数将时间以固定的格式显示出来,
两者的返回值都是char*型的字符串。返回的时间格式为:
星期几 月份 日期 时:分:秒 年\n\0
例如:Wed Jan 02 02:03:55 1980\n\0
其中/n是一个换行符,/0是一个空字符,表示字符串结束。下面是两个函数的原型:
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);
其中asctime()函数是通过tm结构来生成具有固定格式的保存时间信息的字符串,
而ctime()是通过日历时间来生成时间字符串。这样的 话,
asctime()函数只是把tm结构对象中的各个域填到时间字符串的相应位置就行了,
而ctime()函数需要先参照本地的时间设置,把日历时间转 化为本地时间,然后再生成格式化后的字符串。
我们可以使用mktime()函数将用tm结构表示的时间转化为日历时间。其函数原型如下:
time_t mktime(struct tm * timeptr);
*/
#include<cstdio>
#include<ctime>
int main()
{
//printf("%d",sizeof(long));
int i=10000000;
clock_t start,finish;
start=clock();
while(i--)
finish=clock();
printf("%ld",finish-start);
time_t timer;
struct tm *p;
timer=time(&timer);//或 timer=time(NULL)
p=gmtime(&timer);
printf("%d",p->tm_hour);
struct tm t;
//struct tm *p;
time_t t_of_day;
t.tm_year=2020-1900;
t.tm_mon=9;
t.tm_mday=28;
t.tm_hour=8;
t.tm_min=45;
t.tm_sec=1;
t_of_day=mktime(&t);
p=gmtime(&t_of_day);
printf("今天是星期:%d\n",p->tm_wday);
printf(ctime(&t_of_day));
return 0;
}
/*
例 :
下面的例子可以计算出1997年7月1日是星期几:
#include "time.h"
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
struct tm t;
time_t t_of_day;
t.tm_year=1997-1900;
t.tm_mon=6;
t.tm_mday=1;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=1;
t.tm_isdst=0;
t_of_day=mktime(&t);
printf(ctime(&t_of_day));
return 0;
}
运行结果:
Tue Jul 01 00:00:01 1997
现在注意了,有了mktime()函数,是不是我们可以操作现在之前的任何时间呢?
你可以通过这种办法算出1945年8月15号是星期几吗?答案是否定的。
因为这个时间在1970年1月1日之前,所以在大多数编译器中,这样的程序虽然可以编译通过,但运行时会异常终止。
*/
随机数
#include<stdlib.h>
#include<time.h>
srand(time(NULL));
int t=rand(); // 0~32767
多线程
#include<stdio.h>
#include<windows.h>
DWORD /*WINAPI*/fun(LPVOID pM)
{
//printf("%d",GetCurrentThreadId());
for(int i=1;;i++)
{
Sleep(1000);
printf("bbb\n");
}
return 0;
}
int main()
{
printf("多线程");
HANDLE handle=CreateThread(NULL,0,fun,NULL,0,NULL);
for(int i=1;;i++)
{
Sleep(1000);
printf("aaa\n");
}
WaitForSingleObject(handle,INFINITE);
return 0;
}
终端
颜色
#include<stdio.h>
#include<windows.h>
void SetColor(unsigned short ForeColor=7,unsigned short BackGroundColor=0)
{
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle,ForeColor+BackGroundColor*0x10);
}
int main()
{
for(int i=0;i<=16;i++)
{
SetColor(0,i);
printf(" \n");
}
return 0;
}
隐藏光标
void hidden_cursor()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=0;
SetConsoleCursorInfo(hOut,&cci);
}
光标位置
void SetPos(int x,int y)
{
COORD coord;
coord.X=y;
coord.Y=x;
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );
}
TCP
client
#include<stdio.h>
#include<windows.h>
SOCKET clientSocket;
int count=0;
void jieshou()
{
char recvBuff[1024];
int r;
while(1)
{
r = recv(clientSocket,recvBuff,1023,NULL);
if(r>0)
{
recvBuff[r]=0;
printf("%s\n",recvBuff);
}
}
}
int main()
{
//1 请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("请求协议版本失败\n");
return -1;
}
//2 创建socket
clientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(SOCKET_ERROR == clientSocket)
{
printf("创建socket失败!\n");
WSACleanup();
return -2;
}
else printf("创建socket成功\n");
//3 获取服务器协议地址族
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET;//协议版本
addr.sin_addr.S_un.S_addr = inet_addr("10.135.94.10");
addr.sin_port = htons(10086);//0~65535 用10000左右的端口
//4 连接服务器
int r = connect(clientSocket,(struct sockaddr*)&addr,sizeof(addr));
if(r==-1)
{
printf("连接服务器失败\n");
return -3;
}
else printf("连接服务器成功\n");
//5 通信
char buff[1024];
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)jieshou,NULL,NULL,NULL);
while(1)
{
memset(buff, 0, 1024);
printf("输入你想说的:");
scanf("%s",buff);
send(clientSocket,buff,strlen(buff),NULL);
}
return 0;
}
server
#include<stdio.h>
#include<windows.h>
SOCKADDR_IN cAddr = {0};
int len = sizeof(cAddr);
SOCKET clientSocket[1024];
int count=0;
void tongxin(int idx)
{
char buff[1024];
int r;
while(1)
{
r = recv(clientSocket[idx],buff,1023,NULL);
if(r>0)
{
buff[r]=0;
printf("%d:%s\n",idx,buff);
//广播数据
int i;
for(i=0;i<count;i++)
{
send(clientSocket[i],buff,strlen(buff),NULL);
}
}
}
}
int main()
{
//1 请求协议版本
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("请求协议版本失败\n");
return -1;
}
//2 创建socket
SOCKET serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(SOCKET_ERROR == serverSocket)
{
printf("创建socket失败!\n");
WSACleanup();;
return -2;
}
else printf("创建socket成功\n");
//3 创建协议地址族
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET;//协议版本
addr.sin_addr.S_un.S_addr = inet_addr("10.135.94.10");
addr.sin_port = htons(10086);//0~65535 用10000左右的端口
//4 绑定
int r = bind(serverSocket,(struct sockaddr*) &addr,sizeof(addr));
if(r == -1)
{
printf("bind失败\n");
closesocket(serverSocket);
WSACleanup();
return -3;
}
else printf("bind成功\n");
//5 监听
r = listen(serverSocket,10);
if(r == -1)
{
printf("listen失败\n");
closesocket(serverSocket);
WSACleanup();
return -4;
}
else printf("listen成功\n");
//6 等待客户端连接
while(1)
{
clientSocket[count] = accept(serverSocket, (struct sockaddr*) &cAddr, &len);
if(SOCKET_ERROR == clientSocket[count])
{
printf("服务器宕机了\n");
closesocket(serverSocket);
WSACleanup();
return -5;
}
else printf("有客户端连接到服务器了:%s\n",inet_ntoa(cAddr.sin_addr));
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)tongxin,(char*)count,NULL,NULL);
count++;
}
//7 通信
char buff[1024];
while(1)
{
r = recv(clientSocket,buff,1023,NULL);
if(r>0)
{
buff[r] = 0;
printf("%s\n",buff);
}
}
return 0;
}
C语言函数与算法
https://shuusui.site/blog/2021/07/02/c/