专业课细节题

指针

指针对应数组位置,地址计算

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>
#include<string.h>
int main(){
int a[3][4]={1,2,3,4,5,6,7,18,19,10,11,12};
int *p=a[0];
p+=6;
printf("%d\n",*p);
printf("%d\n",*(*(a+2)+3));
printf("%d\n",*(a[1]+3));
printf("%d",*(&a[0][0]+8));
return 0;
}

结果

1
2
3
4
7
12
18
19

指针数组比较

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#include<string.h>
int main(){
char *language[10]={"FORTRAN","BASIC","PASCAL","JAVA","C"};
printf("%s\n",language[1]);
printf("%s\n",language[2]);
printf("%c\n",*language[1]);
printf("%c",*language[2]);
return 0;
}

结果是

1
2
3
4
BASIC
PASCAL
B
P

字符串输入输出

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
#include<string.h>
int main(){
char a1[6],a2[6],a3[6],a4[6];
scanf("%s%s",a1,a2);
gets(a3);
gets(a4);
puts(a1);
puts(a2);
puts(a3);
puts(a4);
return 0;
}

结果是

1
2
3
4
5
6
aa bb
cc dd
aa
bb

cc dd

求精确值

π /2=1+1/3+1/3 * 2/5+1/3 * 2/5 * 3/7 + 1/3 * 2/5 * 3/7 +1/3 * 2/5 * 3/7 *4/9 +

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
#include<string.h>
int main(){
double s=1.0,eps,t=1.0;
int n;
scanf("%lf",&eps);
for(n=1;n<eps;n++){
t=t*n/(2*n+1);
s+=t;
}
printf("%lf",s);
return 0;
}

10以内的约数

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
#include<string.h>
int main(){
int a[10],n;
int i,j=0;
scanf("%d",&n);
for(i=1;i<n;i++)
if(n%i==0)
a[j++]=i;
for(i=0;i<j;i++)
printf(" %6d",a[i]);
return 0;
}

结果是

1 2 5

数组反转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
#include<string.h>
//int x[100],n;
void ive(int x[],int n){
int t,*p;
p=x+n-1;
while(x<p){
t=*x;
*x++=*p;
*p--=t;
}
}
int main(){
int i,a[]={1,2,3,4,5,6,7,8,9,0};
ive(a,10);
for(i=0;i<10;i++)
printf("%d",a[i]);
printf("\n");
return 0;
}

结果

1
2
3
4
0987654321
对于*x++相当于*(x++)若对应x[0] *p--相当于*(p--)
先保存x[0]将最后一个p[n-1]赋值给x[0],再将p[n-1]赋值初始的x[0]
总体而言即交换第一个最后一个,第二个倒数第二个,第三个倒数第三个……以此类推,完成倒序数组

改变字符串位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<string.h>
void fun(char *w,int n){
char t,*s1,*s2;
s1=w;
s2=w+n-1;
while(s1<s2){
t=*s1++;
*s1=*s2--;
*s2=t;
}
}
int main(){
static char p[]="1234567";
fun(p,strlen(p));
printf("%s",p);
return 0;
}

结果是

1
2
3
4
1711717
第一个不变,t=s1[0]=1,s1[1]=s2[6]=7,s2[5]=t=1,第二个和倒数第二个改变 w="1734517"
第二个不变,t=s1[1]=7,s1[2]=s2[5]=1,s2[4]=t=7,第三个和倒数第三个改变w="1714717"
第三个不变,t=s[2]=1,s1[3]=s2[4]=7,s2[3]=t=1;第四个和倒数第四个即中间一个变w="1711717"

上一题的细节,字符串数组和字符数组长度和大小的问题

1
2
3
4
5
6
7
8
#include<stdio.h>
#include<string.h>
int main(){
char p[]="1234567";
char a[8]={'i','l','o','v','e','y','o','u'};
printf("%d %d %d %d",strlen(p),strlen(a),sizeof(p),sizeof(a));
return 0;
}

结果

1
2
3
7 8 8 8
第一个字符串数组p的数字只有7个,所以长度是7,但是大小要算上最后的一个'\0',所以为8
第二个字符数组a的字符个数有八个,所以长度为8,大小也为8

结构体指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
struct str1{
char c[5];
char *s;
};
int main(){
struct str1 s1[2]{{"ABCD","EFGH"},{"IJK","LMN"}};
struct str2{
struct str1 sr;
int d;
}s2={"OPQ","RST",32767};
struct str1 *p[2];
p[0]=&s1[0];
p[1]=&s1[1];
printf("%s\n",++p[1]->s);
printf("%c",s2.sr.c[2]);
return 0;
}

结果是

1
2
3
4
5
MN
Q
对于字符串s输出,若在前面写出++s,若当前下标为0则从下标1处输出整个字符串。
指针数组指针p[0]指向s1[0]所在地址,p[1]指向s1[1]所在地址
对于字符串指针数组可以用++p[1]->s来输出,但对于字符串数组只能直接调用,p[1]->c不能在前面和后面进行++

三维指针数组找变量值

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
#include<string.h>

char *pp[2][3]={"abc","defgh","ijkl","mnopqr","stuvw","xyz"};
int main(){

printf("%c\n",***(pp+1));//m
printf("%c\n",**pp[0]);//a
printf("%c\n",(*(*(pp+1)+1))[4]);//w
printf("%c\n",*(pp[1][2]+2));//z
printf("%s",**(pp+1));//defgh
return 0;
}

结果

1
2
3
4
5
6
m
a
w
z
mnopqr
三维数组比较抽象,默认去掉一个*就可以清晰很多了。

递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<string.h>
void fun(int n,int *s){
int f1,f2;
if(n==1||n==2)
*s=1;
else{
fun(n-1,&f1);
fun(n-2,&f2);
*s=f1+f2;
}
}
int main(){
int x;
fun(6,&x);
printf("%d",x);
return 0;
}

结果

1
2
8
迭代 f(1)=f(2)=1 f(3)=f(1)+f(2)=2 f(4)=f(3)+f(2)=2+1=3 f(5)=f(4)+f(3)=3+2=5 f(6)=f(5)+f(4)=5+3=8

共用体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
#include<string.h>
int main(){
union E{
struct{
int x,y;
}in;
int a,b;
}e;
e.a=1;e.b=2;
e.in.x=e.a*e.b;
e.in.y=e.a+e.b;
printf("%d\n%d",e.in.x,e.in.y);
return 0;
}

结果

1
2
4
8