一面面试题


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

一。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<stdio.h>
#include<stdbool.h>
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<stdio.h>
#include<stdbool.h>
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,3
            ave = 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进制=0xffffffff
	int c=-1;			//c和
	unsigned short d = c*256;
	c <<= 4;			//c
	int e = 2;
	e = ~e|6;			//e
	d=(d & 0xff) + 0x2022;//d
	printf("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 <stdio.h> 
#include<string.h>
char* Strcpy(char *p,const char *q)
{
	assert((p!=NULL)&&(q!=NULL));//判断非空 
	char *m=p;// 
	while(*q)
	{
	 *p++ = *q++;
	}//实现1 
	/*
	实现2
	while((*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 <stdio.h> 


   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;	
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值