一面面试题

文章目录

  • 一。3g
    • 1.反转字符串
    • 2.超出long long 范围,用llu输出
    • 3.判断子字符串
    • 4. 杨辉三角
    • 5.前n素数和
      • 判断素数(注意是素数不是奇数)3种
    • 6.各种楼梯,for循环
    • 7. 1013. 将数组分成和相等的三个部分
    • 8. 171.转化为26进制,excel表中的字母转数字
    • 9。581 找出一个连续子数组,输出它的长度
  • 二。 linux
    • 1.const位置
    • 2.数据类型范围,转化16进制
  • 三。3g大一下学期
    • 1.解释传址![](https://img-blog.csdnimg.cn/72c4a8379da844d3bcb29e4f9c9cb79e.png)
    • 2.一维数组与指针
    • 3.自增运算符
    • 4.实现strcpy
    • 5.指针与数组区别
    • 6.字符串指针数组
    • 7.结构体内存对齐
    • 8.死循环
    • 9数组中找出最大三个数
    • 10.判断环形链表

学到了的话,请留下您的足迹,点赞了再走吧。

一。3g

1.反转字符串

int main()
{char a[20]={0};char b[20]={0};printf("输入第一个字符串:\n");scanf("%s",a);printf("输入第二个字符串:\n");scanf("%s",b);int i=0,j=0,n=strlen(a),m=strlen(b);while(i<n&&j<m){if(a[i]==b[j]){i++;}j++;		//第一个字符串中每一位与第二个字符串**对应位的后面的**字符比对} if(i==n) printf("true");else printf("false"); 
} 

2.超出long long 范围,用llu输出

int main()
{long long b = 0;long long k = 0, n;int i;printf("输入数组\n");scanf("%llu", &b);//	for(i=0;i<20;i++)//	{//		scanf("%lld",&a[i]); //		//	}//	for(i=0;i<20;i++)//	{//		n += a[i]*pow(10,20-i-1);//	 } printf("输入一个数:\n");scanf("%I64d", &k);long long m = b + k;printf("%llu", m);return 0;
}

注意类型一致,long long,输入时可以用lld (最长19位), 而输出时用llu 为20位的无符号长整形,作为超出long long取值范围的输出。
偷懒记:
signed char -128~127 (3位) 无符号* 2
short int -3万到3万(5位)无符号* 2
float 负3百万~ (7位)精确到6位
double 负4~ (16位)精确到15位
int 范围 -20亿到20亿(10位)无符号*2
long int 或 long 和int一样
long long -9到9 (19位)
unsigned long long (20)位

3.判断子字符串

int main()
{char a[20]={0};char b[20]={0};printf("输入第一个字符串:\n");scanf("%s",a);printf("输入第二个字符串:\n");scanf("%s",b);int i=0,j=0,n=strlen(a),m=strlen(b);while(i<n&&j<m){if(a[i]==b[j]){i++;}j++;} if(i==n) printf("true");else printf("false"); 
} 

双指针类型

4. 杨辉三角

int main()
{int i,j,n,a[100][100]={0};printf("输入你将打印的杨辉三角的行数:\n");scanf("%d",&n);printf("\n");for(i=0;i<n;i++){a[i][0]=a[i][i]=1; }//先打印每行开始和结束的for(i=2;i<n;i++){for(j=1;j<i;j++){a[i][j]=a[i-1][j-1]+a[i-1][j];}}//从第三行第二列开始,就是上面一行两个数之和for(i=0;i<n;i++){for(j=0;j<=i;j++){printf("%d",a[i][j]);} printf("\n");}//打印所有 return 0;
}

5.前n素数和

void Isprime(int n)
{int i,j,sum=0;int m=sqrt(n);if(m==0)printf("Error!\n");else if(m==1)printf("None\n");else if(m>=2){for(i=1;i<=n;i+=2)//被除数是奇数 {for(j=2;j<=sqrt(n);j++)//除数小于根 if(i%j==0)break;//偶数 if(i>=m+1)	//判断素数公式 printf("%d\t",i);sum+=i;printf("\n");}}printf("素数和为:%d\n",sum);
}int main()
{int a[20]={0},i,sum=0,n;printf("你将求多少以内的素数和:\n");scanf("%d",&n);Isprime(n);return 0;
}

判断素数(注意是素数不是奇数)3种

1.最简朴,挨个遍历,判断素数
#include
#include
bool f(int a)
{int i;if(a==1) return false;for(i=2;i<a;i++){if(a%i==0)	return false;}return true;
}int main()
{int a;scanf("%d",&a);if(f(a)) printf("是素数.");else printf("不是素数."); return 0;
}
2.优化,除2以外,只需判断所有的奇数是否是素数
#include
#include
bool f(int a)
{int i;if(a==1) return false;//1既不是素数也不是偶数,if(a==2) return true;if(a%2!=0) //仅判断所有的奇数是否是素数 {for(i=2;i<a;i++){if(a%i!=0) return true; }}return false;
}int main()
{int a;scanf("%d",&a);if(f(a)) printf("是素数.");else printf("不是素数."); return 0;
}
3.从2到 sqrtn均整除判断,一个合数一定含有小于它平方根的质因子
bool f(int a)
{int i;if(a==1) return false;for(i=2;i<=sqrt(a);i++){if(a%i==0)	return false;}return true;
}

参考:素数判断
4.素数筛(输出范围内的素数)
素数筛选法:就是当i是素数的时候,i的所有的倍数必然是合数。如果i已经被判断不是质数了,那么再找到i后面的质数来把这个质数的倍数筛掉。
在这里插入图片描述

bool flag[10000];
int main()
{int a,i,j,sum=0;//s scanf("%d",&a);//a范围内int p[a];for(i=2;i<=a;i++)//先把所有标记为1 {p[i]=1;}for(i=2;i<=sqrt(a);i++)//标记根a内数,的倍数0 {if(!flag[i])for(j=i+i;j<=a;j+=i)//倍数标记 {flag[j]=true; }}	for(i=2;i<=a;i++){if(!flag[i])//没有被标记的数字放在一个数组 {p[sum++]=i;}} for(i=0;;i++){if(p[i]==1) break;printf("%d ",p[i]);}return 0;
}

6.各种楼梯,for循环

void Daojisan()
{int i,j;for(i=1;i<=5;i++){for(j=0;j<i;j++){printf(" ");}for(j=1;j<=(-2)*i+11;j++){printf("*");}printf("\n");}}void Lingxing()
{int i,j;for(i=1;i<=5;i++){//	for(j=5-i;j>0;j--)for(j=1;j<=(-1)*i+6;j++){printf(" ");}for(j=1;j<=2*i-1;j++){printf("*");}printf("\n");}for(i=1;i<5;i++){for(j=1;j<=i+1;j++){printf(" ");}for(j=1;j<=(-2)*i+9;j++){printf("*");}printf("\n");}
}void Zhengsanjiao()
{int i=0;int j=0;for(i=5;i>0;i--){for(j=i+2;j>0;j--){printf(" ");	}for(j=(2*i+1);j<=13;j++){printf("*");}	printf("\n");				}
}
int main()
{Daojisan();Lingxing();Zhengsanjiao();return 0;
}

7. 1013. 将数组分成和相等的三个部分

①直接找

int main()
{int sum = 0,i=0;int arr[10]={0};int arrSize;printf("你输入的数组多长:\n");scanf("%d",&arrSize);for(i=0;i<arrSize;i++){scanf("%d",&arr[i]);	}for (i = 0; i < arrSize; ++i) {sum += arr[i];}if (sum % 3 != 0) {printf("FALSE");return 0;}//.先求数组和,排除不能整除3的数组int ave = 0, cnt = 0;for (i = 0; i < arrSize; ++i) {ave += arr[i];			//计算数组平均三堆的值if (ave == sum / 3) {	//不断判定平均数cnt++;          	//统计可以被均分的堆数1,2,3ave = 0;			//归零平均数}}if(cnt == 3 && ave)			//可以被均分3堆并且均非空{printf("true");}else {printf("false");}
}`

这里仅·对于false可以返回
②双指针

{int left=0,right=n-1;int leftsum=a[left],rightsum=a[right];ave = sum/3;while(left+1<right){if(leftsum == ave && rightsum == ave && ave != 0){printf("true");return 0;}if(leftsum != sum/3 ){leftsum += a[++left];}if(rightsum != sum/3){rightsum += a[--right];}}	printf("false");return0;}

这里对于true可以作正确返回,但是对于false什么都不显示,求高人指点

8. 171.转化为26进制,excel表中的字母转数字

int main()
{long long n=0,t=1,i=0;char s[26] = {0};printf("你将转化的字母是:\n");scanf("%s",s);int m=strlen(s);for(i=m-1;i>=0;i--){n += t*(s[i]-'A'+1);		//我一直很颠倒ANSI码的使用,这里使用单引号作差可以得到数字差值,加一即表示 excel中字母的大小 t*=26; 						//①t=pow(26,0) ②t=pow(26,1)... }printf("转化成数字是:%d\n",n);return 0;
}

我一直很颠倒ANSI码的使用,这里使用单引号作差可以得到数字差值,加一即表示 excel中字母的大小 ,再乘以26的位置次方可得到数字值

9。581 找出一个连续子数组,输出它的长度

int main()
{int a[10]={0},n,i=0,j=0;printf("你的数组多长:\n");scanf("%d",&n);printf("输出你的数组:\n");for(i=0;i<n;i++){scanf("%d",&a[i]);}int min=a[0],max=a[0];for(i=0;i<n-1;i++){for(j=i+1;j<n;j++){if(a[0]>a[j]){min=a[j];}if(a[j]>a[i]){max=a[j];}	}}printf("min=%d max=%d\n",min,max);int p=n-2,q=n-1,h=0;if(a[0]==min&&a[n-1]==max){printf("最短数组长%d\n",p);}else if(a[0]==min||a[n-1]==max) {printf("最短数组长%d\n",q);}else printf("最短数组长%d",h);return 0;
}

这里采用选择跳出最值,用最值调出左右边界进行计算。

二。 linux

1.const位置

①const 对后面紧跟的 变量类型 起作用(不可更改)
例:int const p; 作用于变量地址
int const *p; 作用于变量的值
② int const p 与 const int p 没有区别,变量类型一致
int const * p 和 const int * p 没有区别,变量类型一致
③ 找错

2.数据类型范围,转化16进制

int main()
{short a = -2;    //a转化为unsigned int b = 1;b += a;			//b的-1无符号转2进制1111 1111 1111 1111 1111 1111 1111 1111转16进制=0xffffffffint c=-1;			//c和unsigned short d = c*256;c <<= 4;			//cint e = 2;e = ~e|6;			//ed=(d & 0xff) + 0x2022;//dprintf("a=0x%hx \n b=0x%x \n d=0x%hx \n e=0x%x \n\n ",a,b,d,e);printf("c=0x%hhx \n",(signed char )c);return 0;
}

前提须知:
先将10进制转化为2进制,再转化为16进制
%x    无符号的16进制数字,并以小写abcdef表示
hd,hx,hu,这几个都是输出16位数据的,
hhd,hhx,hhu,hho,这几个都是输出8位的10进制、16进制、无符号10进制、8进制,
运行结果
a=0xfffe
b=0xffffffff
d=0x2022
e=0xffffffff

c=0xfff0

三。3g大一下学期

1.解释传址

2.一维数组与指针

在这里插入图片描述
第一个
输出的是: 4 4
①4:* (a+3)就是 a[3] ,数组的第四个元素,即4
② 4:&a代表的是整个数组的地址,而&a+1是跳过整 个数组的地址, int* par = (int*)(&a + 1); 是让指针指向整个数组之后的地址,而par-2是元素地址向前2个单位,*(par-2)为其解引用得到指针内容,4

第二个
输出的是 :2,6487564,6487556
① 2 :这里注意 数组名表示首元素地址,那么a+3就表示第4个元素地址,指针指向第四个元素地址,下标法表示b[0] 或者解引用 *b都是4,那么b[-2] = *(b-2),地址向前两个单位进行解引用得到 2
②③都是表示地址前者是第四个元素地址,后者是第二个元素地址,相差2 * 4 = 8个字节大小

3.自增运算符

在这里插入图片描述
条件选择符
a>b ? a:b
输出(编译器不同,有的以运算优先顺序为主,有的以结合性优先,结果不同)
5 1
4
注意:自增减运算符同理
若a=1;a++是先取值后自增,先给(a++)取值为1,然后(自增) a值为2;
++a是先自增后取值,则(++a)值为2,a的值为2
在这里插入图片描述
而选择x–输出x及自减后得到4

4.实现strcpy

在这里插入图片描述

#include  
#include
char* Strcpy(char *p,const char *q)
{assert((p!=NULL)&&(q!=NULL));//判断非空 char *m=p;// while(*q){*p++ = *q++;}//实现1 /*实现2while((*p++ = *q++)!='\0)*/return m;
}
int main()
{char a[10];char b[10]="def";printf("%s\n",Strcpy(a,b)); return 0;
}

5.指针与数组区别

在这里插入图片描述
1.指针与数组的区别:

数组是开辟一块连续的内存空间,数组本身的标示符代表整个数组,可以用sizeof取得真实的大小;
指针则是只分配一个指针大小的内存,并可把它的值指向某个有效的内存空间
2.为什么可以s = a;不可以a = s

s是一个可以变化的指针变量,而a是一个指针常量。数组a的地址也就是固定的,s的地址随机
数组名a就是该数组的首地址,也是数组第一个元素的地址;
C语言对数组的访问是通过数组名(数组的起始地址)
加上相对于起始地址的相对量(由下标变量给出),得到要访问的数组元素的单元地址,
然后再对计算出的单元地址的内容进行访问。

指针(访问)指向数组首地址,可以访问内一片连续的固定内存空间,但是固定地址无法访问随机地址

6.字符串指针数组

在这里插入图片描述
字符串指针数组:
数组里的内容是*型
str的类型是char *[]型

  • str——"This"的地址 ,str+1——"is"的地址
  • *str——"This"的首地址,即 ’T‘ 的地址 , * (str+1)——“is”的首地址即 ‘i’ 的地址
  • *(str+1)+1 即 ’s‘ 的地址
  • . * ( *(str+1)+1)对 ‘s’ 地址取值即 ‘s’
  • **str——‘T’

str+1是p指向 "is"地址
(*p++) + 2:++优先级高于 * ,(p++)还是is地址,对其解引用得到值(*p++)就是首元素 i,
(p自增指向 “xiyou” ),(*p++) + 1是 s 元素,(*p++) + 2是 ’\n‘
*(p+1): 注意此时的 p 是 "xiyou"的地址,p+1就是 "mobile"的地址,解引用得到字符串

7.结构体内存对齐

在这里插入图片描述
1.switch里面
没有break就一值打印,直到遇见break;
2.
a=10;
cnt=printf("%d\n",a);printf返回的是 字符个数,‘1’ ‘2’ ‘\n’ 是3个字符故cnt=3;
3.
结构体,联合体对齐规则:
① 结构体 的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
②如果一个 结构体B 里嵌套另一个结构体A,以两个结构体内部最长的类型为基准长度
③ 联合体 的内存除了取最大成员内存外,还要保证是所有成员类型size的最小公倍数

输出:12, 35,40 
  • 联合体 b 的字节对齐:取最长类型char数组的10,但是int是4字节的,而此时联合体已经按char的1字节对齐了,所以还要额外多加2字节的内存来保证4的倍数。12
  • 结构体 g 的字节对齐:取最double作为基准长度,联合体按照8 * 1+4 * 1=12对齐,接下来int按照4 * 1=4对齐,此时对齐82=16,double按照18 * 1=8对齐,char 按照1 * 1对齐,余下补0,总字节84=32

1.b字节12
2.cnt 按照printf的返回字符个数,‘1’ ‘2’ ‘\n’返回3个字符,g字节32,cnt=cnt+32=35
3.
cnt+=1[nums];这里nums[1]等价于1[nums]
因为
C在预编译后是不会有[]的,会转换为指针
num[1]== * (nums+1)==
* (1+nums)== 1[nums] ==5哦
40 == 5+35

8.死循环

在这里插入图片描述
计算机内部是以二进制来存贮数值
char默认为(signed char) 类型的范围为 -128~127
signed char 类型的范围为 -128~127
总共 signed char 有 256 个数
unsigned char 的范围为 0~ 255

输出
first=-1,second=-1,third=255
欢迎加入3G!+255(死循环不断打印)

char first_num = -1; 范围内
signed char second_num = -1;范围内
unsigned char third_num = -1; 超出范围

third_num为unsigned 无符号, 它的八位都用来存储数值, 没有符号位,编译器把 -1 转换为补码为 1111 1111,但由于是无符号,计算机会把 1111 11111 当做是无符号来对待,自然就是 2^8 -1 = 255
没有third_num <= 255&&third_num >0的条件限制运作到third_num<0无法终止,继续从255开始减小不断打印

9数组中找出最大三个数

在这里插入图片描述

#include  int main(){int a[100]={0},b[3]={0},n=0,i=0,j=0,t=0;printf("输入数组大小:\n");scanf("%d",&n);printf("输入数组:\n");for(i=0;i<n;i++){scanf("%d",&a[i]);}for(i=0;i<n;i++){for(j=0;j<n-1-i;j++){if(a[j]<a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}}}for(i=0;i<3;i++){b[i]=a[i];printf("%d\n",b[i]);}return 0;}

想法:定义两个数组,给输入的数组排序,拿出前三个放在第二个数组,输出

10.判断环形链表

int Panduan(Link head)
{Node *fast=head,*slow=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(fast==slow){return 1;}}return 0;	
}

详情见小白也会
学到了的话,请留下您的足迹,点赞了再走吧。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部