大厂技术面试题汇总,《华为专项题大全》
简答题
1、局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用"::" ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
2、如何引用一个已经定义过的全局变量?
答:extern 可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个编写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错.
4、请写出下列代码的输出内容
#include <stdio.h>
int main(void)
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
答:10,12,120
5、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答: 1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
综上所述:
static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
6、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。
7、设有以下说明和定义
typedef union
{
long i;
int k[5];
char c;
} DATE;
struct data
{
int cat;
DATE cow;
double dog;
} too;
DATE max;
则语句 printf("%d",sizeof(struct data)+sizeof(max));的执行结果是:52_
考点:区别struct与union.(一般假定在32位机器上)
答:DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20. data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52. 当然…在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20
8、队列和栈有什么区别?
队列先进先出,栈后进先出
9、写出下列代码的输出内
#include <stdio.h>
int inc(int a)
{ return(++a); }
int multi(int*a,int*b,int*c)
{ return(*c=*a**b); }
typedef int(FUNC1)(int in);
typedef int(FUNC2) (int*,int*,int*);
void show(FUNC2 fun,int arg1, int*arg2)
{
FUNC1 p=&inc;
int temp =p(arg1);
fun(&temp,&arg1, arg2);
printf("%dn",*arg2);
}
main()
{
int a; //局部变量a为0;
show(multi,10,&a);
return 0;
}
答:110
10、请找出下面代码中的所有错误 (题目不错,值得一看)
说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”
答:
方法1:一共有4个错误;
int main()
{
char* src = "hello,world";
int len = strlen(src);
char* dest = (char*)malloc(len+1);//要为分配一个空间 char* d = dest;
char *d=dest;
char* s = &src[len-1]; //指向最后一个字符
while( len– != 0 )
*d++=*s–;
*d = 0; //尾部要加’\0’
printf("%sn",dest);
free(dest); // 使用完,应当释放空间,以免造成内存汇泄露
dest = NULL; //防止产生野指针
return 0;
}
方法2: (方法一需要额外的存储空间,效率不高.) 不错的想法
#include <stdio.h>
#include <string.h>
main()
{
char str[]="hello,world";
int len=strlen(str);
char t;
for(int i=0; i<len/2; i++)
{
t=str[i];
str[i]=str[len-i-1]; //小心一点
str[len-i-1]=t;
}
printf("%s",str);
return 0;
}
11、对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
c用宏定义,c++用inline
12、直接链接两个信令点的一组链路称作什么?
PPP点到点连接
13、接入网用的是什么接口?
V5接口
14、voip都用了那些协议?
H.323协议簇、SIP协议、Skype协议、H.248和MGCP协议
15、软件测试都有那些种类?
黑盒:针对系统功能的测试
白盒:测试函数功能,各函数接口
16、确定模块的功能和模块的接口是在软件设计的那个队段完成的?
概要设计阶段
17.
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问:p1+5=? p2+5=?
答案:0x801005(相当于加上5位) ;0x810014(相当于加上20位);
选择题:
21、Ethternet链接到Internet用到以下那个协议? (D)
A.HDLC; B.ARP; C.UDP; D.TCP; E.ID
22、属于网络层协议的是 ( B C)
A.TCP; B.IP; C.ICMP; D.X.25
23、Windows消息调度机制是 ©
A.指令队列; B.指令堆栈; C.消息队列; D.消息堆栈;
找错题
1、请问下面程序有什么错误?
int a[60][250][1000],i,j,k;
for(k=0;k<=1000;k++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
a[i][j][k]=0;
答: 把循环语句内外换一下
2、
#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB * pmsg)
{
unsigned char ucCmdNum;
……
for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
{
……;
}
}
答: 死循环,unsigned int的取值范围是0~255
3、以下是求一个数的平方的程序,请找出错误
#define SQUARE(a) ((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
答:结果与编译器相关,得到的可能不是平方值.
问答题
29、IP Phone的原理是什么?
IP电话(又称IP PHONE或VoIP)是建立在IP技术上的分组化、数字化传输技术,其基本原理是:通过语音压缩算法对语音数据进行压缩编码处理,然后把这些语音数据按IP等相关协议进行打包,经过IP网络把数据包传输到接收地,再把这些语音数据包串起来,经过解码解压处理后,恢复成原来的语音信号,从而达到由IP网络传送语音的目的。
30、TCP/IP通信建立的过程怎样,端口有什么作用?
三次握手,确定是哪个应用程序使用该协议
31、1号信令和7号信令有什么区别,我国某前广泛使用的是那一种?
1号信令接续慢,但是稳定,可靠。
7号信令的特点是:信令速度快,具有提供大量信令的潜力,具有改变和增加信令的灵活性,便于开放新业务,在通话时可以随意处理信令,成本低。目前得到广泛应用。
32、列举5种以上的电话新业务
如“闹钟服务”、“免干扰服务”、“热线服务”、“转移呼叫”、“遇忙回叫”、“缺席用户服务”、“追查恶意呼叫”、“三方通话”、“会议电话”、“呼出限制”、“来电显示”、“虚拟网电话”等
如今软件开发行业正在全球范围内快速发展。因此,重要的是要掌握最值得信任及最通用的编程语言,C/C++非你莫属,毫无争议。我们不必精通所有的语言,但在您的简历书写掌握的语言越多,那么面试官和开发团队就越希望与您合作,在这竞争激烈的行业中建立前途似锦的职业生涯,规划好自己的学习计划明确目标,并在大学期间就开始一一学习,将来的您定会成为这个蓬勃发展领域的顶级专家。
其一C语言无论在编程语言排行榜中,仍然强势排行前3名,其二目前我们中国985/211世界一流高校、国内著名大学计算机及其相关专业开设C语言将其列为重点科目,其重要性就不用我说,其它的编程语言很难也无法超越这一点,所以咱们要珍惜在大学4年期间一定要把自己的专业课学好,为将来工作岗位打下坚实的基础。
1、【题目】水仙花数
水仙花数(Narcissistic number)又被称为阿姆斯特朗数(Armstrong number)。水仙花数是指一个3位数,它的每个位上的数字的3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。
【程序分析】:
使用for循环语言来控制100-999个数,将每个数分解出个位/十位/百位。
【程序源码】:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i, j, k, n;
printf("\n输出100–999所有的水仙花数:\n");
for (n = 100; n <= 999; n++) // 循环每个数字往循环体里面去判断
{
i = n / 100; /*分解出百位*/
j = n / 10 % 10; /*分解出十位*/
k = n % 10; /*分解出个位*/
/* 个位十位百位的立方和等于该数的本身n ,则输出该水仙花数*/
if (n == (i * i * i + j * j * j + k * k * k))
{
printf("%5d", n); // %5d表示以十进制格式输出,宽度为5
}
}
printf("\n");
return 0;
}
2、【题目】斐波那契数列
古典问题:斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
【程序分析】:
兔子的规律为数列:0、1、1、2、3、5、8、13、21、34、……..。
【程序源码】:
#include <stdio.h>
int main(int argc, char *argv[])
{
long f1, f2;
f1 = f2 = 1;
printf("\n输出斐波那契数列20项数据如下:\n");
for (int i = 1; i <= 20; i++)
{
printf("%12ld %12ld", f1, f2);
if (i % 2 == 0) /* 控制输出每行四个数字 */
printf("\n");
f1 = f1 + f2; /* 前两个月加起来赋值给第三个月 */
f2 = f1 + f2; /* 前两个月加起来赋值给第三个月 */
}
printf("\n");
return 0;
}
3、【题目】猴子吃桃问题
猴子吃桃问题:猴子第一天吃了若干个桃子,当即吃了一半,还不解馋,又多吃了一个; 第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。问第一天共吃了多少个桃子?
【程序分析】:
采取逆向思维的方法,从后往前推断。第10天剩一个,前一天则为d9 = (d10 +1)*2,以此推算前一天。可以采用递归如下:
Day10————————-1
Day9————————- 4
Day8———————— 10
Day7————————-22
Day6————————-46
Day5————————-94
Day4————————-190
Day3————————-382
Day2————————-766
Day1————————-1534
【程序源码】:
#include <stdio.h>
int main(int argc, char *argv[])
{
int day = 9;
int x1, x2; /* x1表示前一天,x2表示后一天 */
x2 = 1; /* 第10天,剩下一个 */
for(;day>=1;day–) /* 从第9天开始递推到第1天 */
{
/* x2表示后一天的 */
x1 = (x2 + 1) * 2;
x2 = x1;
}
printf("\n\n猴子第一天共计摘下:%d个桃子\n\n", x1);
return 0;
}
4、【题目】物体自由落地
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
【程序分析】:
根据源程序如下进行详细分析。
【程序源码】:
#include <stdio.h>
int main(int argc, char *argv[])
{
double sn = 100.0, hn = sn / 2;
for (int n = 2; n <= 10; n++)
{
sn = sn + 2 * hn;/*第n次落地时共经过的米数*/
hn = hn / 2; /*第n次反跳高度*/
}
printf("\n球所经过的路程为:%lf米\n", sn);
printf("第10次反弹调度为:%lf米\n\n", hn);
return 0;
}
5、【题目】矩阵对角线元素之和
求一个3*3矩阵对角线元素之和。
【程序分析】:
使用双重for循环控制输入二维数组,再将a[i]i](a[0]0]、a[1][1]、a[2][2])累加,则进行输出。
【程序源码】:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[3][3], sum = 0;
printf("\n请输入矩阵元素值(3*3):\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
scanf_s("%d", &a[i][j]);
}
}
printf("\n输出矩阵(3*3)数据如下:\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%4d", a[i][j]);
}
printf("\n");
}
printf("\n");
// 求对角线之和
for (int i = 0; i < 3; i++)
sum = sum + a[i][i];
printf("\n矩阵对角线(3*3)元素之和为:%d\n\n", sum);
return 0;
}
6、【题目】求素数
判断101-200之间有多少个素数,并输出所有素数。
【程序分析】:
判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。
【程序源码】:
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
int _tmain(int argc, _TCHAR* argv[])
{
int m, i, k, h = 0, leap = 1;
printf("\n");
for (m = 101; m <= 200; m++)
{
k = sqrt(double(m + 1));
for (i = 2; i <= k; i++)
if (m%i == 0)
{
leap = 0; break;
}
if (leap) {
printf("%-4d", m); h++;
if (h % 10 == 0)
printf("\n");
}
leap = 1;
}
printf("\n101到200之间共计有: %d个素数\n\n", h);
printf("\n\n需要配套详细讲解录播视频,请加上天狼老师sigusoft:726920220\n\n");
return 0;
}
7、【题目】最大公约数和最小公倍数
输入两个正整数m和n,求其最大公约数和最小公倍数。
【程序分析】:
利用辗除法
【程序源码】:
#include <stdio.h>
int main()
{
int a, b, num1, num2, temp;
printf("请输入两个整数:\n");
scanf_s("%d,%d", &num1, &num2);
if (num1 < num2)
{
temp = num1;
num1 = num2;
num2 = temp;
}
a = num1; b = num2;
while (b != 0)/*利用辗除法,直到b为0为止*/
{
temp = a % b;
a = b;
b = temp;
}
printf("最大公约数:%d\n", a);
printf("最小公倍数:%d\n", num1*num2 / a);
return 0;
}
8、【题目】企业发放的奖金根据利润提成。
企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数?
【程序分析】:
请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。
【程序源码】:
#include <stdio.h>
int main()
{
long int i;
int bonus1, bonus2, bonus4, bonus6, bonus10, bonus;
printf("请输入利润金额:");
scanf_s("%ld", &i);
bonus1 = 100000 * 0.1;
bonus2 = bonus1 + 100000 * 0.075;
bonus4 = bonus2 + 200000 * 0.05;
bonus6 = bonus4 + 200000 * 0.03;
bonus10 = bonus6 + 400000 * 0.015;
if (i <= 100000)
bonus = i * 0.1;
else if (i <= 200000)
bonus = bonus1 + (i – 100000)*0.075;
else if (i <= 400000)
bonus = bonus2 + (i – 200000)*0.05;
else if (i <= 600000)
bonus = bonus4 + (i – 400000)*0.03;
else if (i <= 1000000)
bonus = bonus6 + (i – 600000)*0.015;
else
bonus = bonus10 + (i – 1000000)*0.01;
printf("%d元获得的资金是=%ld",i,bonus);
return 0;
}
9、【题目】打印出菱形图案
*
***
******
********
******
***
*
【程序分析】:
先把图形分成两部分来看待,前四行一个规律,后三行一个规律,利用双重for循环,第一层控制行,第二层控制列。
【程序源码】:
#include <stdio.h>
int main()
{
for (int i = 0; i <= 3; i++) // 控制前4行
{
for (int j = 0; j <= 2 – i; j++) // 打印空格
printf(" ");
for (int k = 0; k <= 2 * i; k++) // 打印*号
printf("*");
printf("\n");
}
for (int i = 0; i <= 2; i++) // 控制后3行
{
for (int j = 0; j <= i; j++) // 打印空格
printf(" ");
for (int k = 0; k <= 4 – 2 * i; k++) // 打印*号
printf("*");
printf("\n");
}
return 0;
}
10、折半查找
前提条件:有序的顺序表。【需要具有随机访问的特性,链表没有】。
基本思想: 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜 素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组 为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn) 。
#include "stdafx.h"
#include<stdio.h>
#define N 10
void Binary_Search(int key, int a[], int n);//向前声明定义函数
//key表示要找的数,a表示数组,n表示数组元素个数
void Binary_Search(int key, int a[], int n)
{
int i, high, low, mid;
int count1 = 0, count = 0;
low = 0;
high = n – 1;
while (high >= low) //保证右下标不小于左下标
{
count++;
//总的来说变得是中间位置相当于把中间位置移到了key那个数那里,所以mid应该处于循环里面
mid = (high + low) / 2;
//说明key在a[mid]的左半边 ,那么最右边的high下标就可以在下标mid基础上往左进一个单位
if (key<a[mid])
high = mid – 1;
//说明key在a[mid]的右半边 ,那么最左边的low下标就可以在下标mid基础上往右进一个单位
else if (key>a[mid])
low = mid + 1;
if (key == a[mid])
{
printf("\n元素找到,一共查找%d次,它处于a[%d]位置上a[%d]=%d\n\n", count, mid, mid, key);
count1++;
break;
}
}
if (count1 == 0)
printf("\n你要查找的元素不存在!!!\n\n");
}
int main()
{
int key=0,a[N] = {10,13,41,68,73,88,90,95,97,100};
// 提示同学们:数组也可以从键盘初始化输入
printf("\n请输入要查找的数字:");
scanf_s("%d", &key);
Binary_Search(key, a,N);
printf("\n");
return 0;
}
11、快速排序
算法思想∶在待排序表L[1…n]中任取⼀个元素pivot作为枢轴(或基准,通常取⾸元素),通过⼀趟排序将待排序表划分为独⽴的两部分L[1…k-1]和L[k+1…n],使得L[1…k-1]中的所有元素⼩于pivot,L[k+1…n]中的所有元素⼤于等于pivot,则pivot放在了其最终位置L(k)上,这个过程称为⼀次“划分”。然后分别递归地对两个⼦表重复上述过程,直⾄每部分内只有⼀个元素或空为⽌,即所有元素放在了其最终位置上。
#include "stdafx.h"
#include <stdio.h>
#define N 10
int qusort(int s[], int start, int end) //自定义函数 qusort()
{
int i, j; //定义变量为基本整型
i = start; //将每组首个元素赋给i
j = end; //将每组末尾元素赋给j
s[0] = s[start]; //设置基准值
while (i<j)
{
while (i<j&&s[0]<s[j])
j–; //位置左移
if (i<j)
{
s[i] = s[j]; //将s[j]放到s[i]的位置上
i++; //位置右移
}
while (i<j&&s[i] <= s[0])
i++; //位置左移
if (i<j)
{
s[j] = s[i]; //将大于基准值的s[j]放到s[i]位置
j–; //位置左移
}
}
s[i] = s[0]; //将基准值放入指定位置
if (start<i)
qusort(s, start, j – 1); //对分割出的部分递归调用qusort()函数
if (i<end)
qusort(s, j + 1, end);
return 0;
}
int main()
{
int a[11], i; //定义数组及变量为基本整型
printf("\n请输入要排序的10个数字:\n");
for (i = 1; i <= N; i++)
scanf_s("%d", &a[i]); //从键盘中输入10个要进行排序的数
qusort(a, 1, N); //调用qusort()函数进行排序
printf("\n快速排序后的顺序结果如下:\n");
for (i = 1; i <= N; i++)
printf("%5d", a[i]); //输出排好序的数组
printf("\n\n");
return 0;
}
12、选择排序法(以从小到大排序为例)
算法思想:
a.在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
b.从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
c.以此类推,直到所有元素均排序完毕。
#include "stdafx.h"
#include <stdio.h>
int main()
{
int i, j, t, a[11]; //定义变量及数组为基本整型
printf("\n请输入10个要排序的数字:\n");
for (i = 1; i<11; i++)
scanf_s("%d", &a[i]); //从键盘中输入要排序的10个数字
//如果前一个数比后一个数大,则利用中间变量t实现两值互换
for (i = 1; i <= 9; i++)
{
for (j = i + 1; j <= 10; j++)
{
if (a[i]>a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
printf("\n经选择排序后的顺序输出:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); //输出排序后的数组
printf("\n\b");
return 0;
}
13、冒泡排序法(从小到大排序为例)
算法思想:
a.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
b.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数,然后将该数固定。
c.针对所有的元素重复以上的步骤,除了最后一个。
d.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
#include "stdafx.h"
#include <stdio.h>
int main()
{
int i, j, t, a[11]; //定义变量及数组为基本整型
printf("\n请输入10个要排序的数字:\n");
for (i = 1; i < 11; i++)
scanf_s("%d", &a[i]); //从键盘中输入10个数
for (i = 1; i < 10; i++) //变量i代表比较的趟数
{
for (j = 1; j<11 – i; j++) //变最j代表每趟两两比较的次数
if (a[j]>a[j + 1])
{
t = a[j]; //产利用中间变童实现两值互换
a[j] = a[j + 1];
a[j + 1] = t;
}
}
printf("\n\n经冒泡排序后的顺序输出:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); //将胃泡排序后的顺序输出
printf("\n\n");
return 0;
}
14、归并排序算法
归并是将两个或多个存序记录序列合并成一个有序序列。归并方法有多种,一次对两个有序记录序列进行归并,称为路归并排序,也有三路归并排序及多路归并排序。本实例是二路归并排序,基本方法如下: (1) 将 n 个记录看成是 n 个长度为 1 的有序子表。 (2) 将两两相邻时有序无表进行归并。 (3) 重复执行步骤 (2) 直到归并成一个长度为 n 的有序表。
#include "stdafx.h"
#include <stdio.h>
int merge(int r[], int s[], int x1, int x2, int x3) //自定义实现一次归并样序的函数
{
int i, j, k;
i = x1; // 第一部分的开始位置
j = x2 + 1; // 第二部分的开始位置
k = x1;
while ((i <= x2) && (j <= x3)) // 当i和j都在两个要合并的部分中时
if (r[i] <= r[j]) // 筛选两部分中较小的元素放到数组s中
{
s[k] = r[i];
i++;
k++;
}
else
{
s[k] = r[j];
j++;
k++;
}
while (i <= x2) // 将x1〜x2范围内未比较的数顺次加到数组r中
s[k++] = r[i++];
while (j <= x3) // 将x2+l〜x3范围内未比较的数顺次加到数组r中
s[k++] = r[j++];
return 0;
}
int merge_sort(int r[], int s[], int m, int n)
{
int p;
int t[20];
if (m == n)
s[m] = r[m];
else
{
p = (m + n) / 2;
merge_sort(r, t, m, p); //递归调用merge_soit()函数将r[m]〜r[p]归并成有序的t[m]〜t[p]
merge_sort(r, t, p + 1, n); //递归一调用merge_sort()函数将r[p+l]〜r[n]归并成有序的t[p+l]〜t[n]
merge(t, s, m, p, n); //调用函数将前两部分归并到s[m]〜s[n]
}
return 0;
}
int main()
{
int a[11];
int i;
printf("\n请输入10个要排序的数字:\n");
for (i = 1; i <= 10; i++)
scanf_s("%d", &a[i]); //从键盘中输入10个数
merge_sort(a, a, 1, 10); //调用merge_sort()函数进行归并排序
printf("归并排序后的顺序输出:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); //输出排序后的数据
printf("\n\n");
return 0;
}
15、希尔排序算法
希尔排序是在直接插入排序的基础上做的改进,也就是将寒排序的序列按固定增量分成若干组,等距者在同二组中,然后再在组内进行直接插入排序。这里面的固定增量从 n/2 开始,以后每次缩小到原来的一半。
#include "stdafx.h"
#include <stdio.h>
int shsort(int s[], int n) /* 自定义函数 shsort()*/
{
int i, j, d;
d = n / 2; /*确定固定增虽值*/
while (d >= 1)
{
for (i = d + 1; i <= n; i++) /*数组下标从d+1开始进行直接插入排序*/
{
s[0] = s[i]; /*设置监视哨*/
j = i – d; /*确定要进行比较的元素的最右边位置*/
while ((j > 0) && (s[0] < s[j]))
{
s[j + d] = s[j]; /*数据右移*/
j = j – d; /*向左移d个位置V*/
}
s[j + d] = s[0]; /*在确定的位罝插入s[i]*/
}
d = d / 2; /*增里变为原来的一半*/
}
return 0;
}
int main()
{
int a[11], i; /*定义数组及变量为基本整型*/
printf("\n请输入10个要排序的数字:\n");
for (i = 1; i <= 10; i++)
scanf_s("%d", &a[i]); /*从键盘中输入10个数字*/
shsort(a, 10); /* 调用 shsort()函数*/
printf("\n\n希尔排序后的顺序输出:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); /*输出排序后的数组*/
printf("\n\n");
return 0;
}
1、为什么C语言这么牛逼和厉害
C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世界的必修课!也是软件开发大神的必修课!也是大学计算机专业必修课!
C语言属于高级语言,具有可移植性,面向过程的,贴近底层、运行速度快,采取结构化程序设计体例,自顶向下、逐步求精。
C语言应用领域:系统软件、应用软件、数字计算、嵌入式设备开发、游戏软件开发、服务器端开发等
【系统软件开发】
操作系统:UNIX、Windows、Linux。
驱动程序:比如主板驱动、显卡驱动、摄像头驱动。驱动一般是用C语言和汇编语言写的,C++在这方面稍弱。
数据库:SQL Server、Oracle、MySQL、DB2。
【应用软件开发】
办公软件:WPS。
图形图像多媒体:Photoshop、Mediaplayer。
嵌入式软件开发:嵌入式软件开发说得简单点就是芯片编程,比如我们以后学习在单片机和 ARM 上进行的开发都属于嵌入式软件开发。
游戏开发:2D、3D 游戏。CS 整个游戏的引擎全部是用纯C写的。
【C语言编译器选择】
编译器:
GCC,GNU组织开发的开源免费的编译器
MinGW,Windows操作系统下的GCC
Clang,开源的BSD协议的基于LLVM的编译器
Visual C++ :: cl.exe,Microsoft VC++自带的编译器
集成开发环境
Code::Blocks,开源免费的C/C++ IDE
CodeLite,开源、跨平台的C/C++集成开发环境
Dev-C++,可移植的C/C++IDE
C-Free
Visual Studio系列(最受欢迎的工具)
2、学习C语言方法与技巧
A.可以先看一些关于C语言的书籍,对C语言有一些了解,可以为自己以后的学习有帮助,知道C语言编程的基本知识,学习C语言主要考验的是逻辑思维和坚持学习的恒心,学习编程特别是语言类的知识,需要多看书多思考多练习。
B.下载和安装一些C语言的编译器,自己进行动手编程,C语言需要通过编译器解释为计算机可以理解的机器码,往往有很多编译器是收费的,接下来小编为大家介绍几款自认为好用的C语言编译器,对于windows系统来说,visual studio是一款不错的编译器;对于Mac系统,XCode适合大部分使用。
C.查看一些基本的代码,自己进行理解编译,想要学好一门编程语言,需要及时的动手练习,如果是没有编程经验的小白可以选择记住一些简单的基本的代码,自己进行练习理解,动手练习是帮助自己快速入门的主要方法。
D.及时的学习和掌握C语言中的语法函数知识,避免一些代码错误的出现,C语言的基础语法包括数据类型,运算符,表达式,数组,逻辑运算,函数,指针等等,需要自己进行记忆和学习。
E.自己进行创作创新,编程的知识学习的差不多了,可以尝试自己创造一个小项目,尝试写一个小程序,比如,开发一个计算机系统,餐馆订餐系统等等。只有尝试着自己开发作品,才能在C语言编程的道路上越走越远。
F、快速入门技巧
选对入门的学习资料很关键,自己很容易看的懂得!
重点学习VC或者GCC编译器的使用,学会调试,基本上就掌握编程的方法了,很多语法基本不用看了,调试是学习编程的不二窍门。
熟能生巧,多动手编程实践和调试,这是第三个诀窍。
【初级阶段】
这个阶段,其实就是入门阶段。在这个阶段的学习方发很简单,看书、做题。不过这个简单的看书做题却又有一些注意事项。就是书看什么书,题做什么题。首先,对于初学来说,我认为看谭浩强的C语言就可以了,毕竟是初学,不必看难度太大、写的太深的书。至于做题,分两种方式,一种是把谭浩强C语言对应的题集买下来,好好的做一遍;另外一种是把这些题再在电脑里面编一遍。纸上做题是为了锻炼思维、巩固基础,电脑上编程才是真正的学以致用,两者都需要进行。相信按照这个过程,会提升你对C语言的兴趣,也能让你快速入门。
【中级阶段】
这个阶段,是对C语言的进阶阶段。这个阶段的学习方法是看书、练习、推敲。这个阶段的重点偏向于C语言语法背后的原理,例如全局变量和局部变量在内存中分配的区别,又比如栈中分配和分配在堆中又有什么区别等等。这个阶段需要看的书应该主要是《C专家编程》、《C陷阱与缺陷》、《C和指针》这样的书。
【高级进阶】
在这个阶段主要是对算法和数据结构上面的学习。入门首先推荐严蔚敏的数据结构。这本书不厚,都是基础的知识,需要将这本书中的知识好好的掌握。这本书学完,数据结构基本上没有问题了,基础算法也了解一些了。那么就可以再学习《算法导论》、《数据结构与算法》,并且选择一些算法自己动手实现。
1、提升程序员的逻辑思维
首先,通过学习数据结构,可以大大拓宽我们的思维模式。掌握了数据结构与算法,我们看待问题的深度、解决问题的角度会大有不同,对于个人逻辑思维的提升,也是质的飞跃。 具体来讲,对于同一个问题,数据结构往往会教给我们不只一种解决思路。举个例子,假设我们需要从众多数据中查找出符合要求的元素,多数人就只能借助数组这种简单的存储结构来实现,而通过学习数据结构我们会知道,解决此类问题既可以通过构建二叉排序树、平衡二叉树、甚至红黑树、B+/B- 树来解决,还可以借助哈希表解决。 再举一个例子,几乎所有的编程语言中都提供有数组这种存储结构,但如果没学过数据结构,就绝不会想到,数组还能以链表的形式使用(也就是静态链表,后续章节会做详细讲解)。 事实上,数据结构也有众多编程语言无法比肩的优势。无论是 Java、Python、C++、PHP 还是其他编程语言,无时无刻不在更新迭代,而数据结构却永远不会过时,其包含的存储数据的思想,已经近乎将所有可能的情况都囊括其中,能解决 99% 的实际场景中有关数据存储的问题。
2、能力高低的分水岭
有很多读者(其中不乏在职的程序员)都会问一个问题,即为什么很多 IT 公司都特别注重对数据结构的考察?读者大可以这样认为:数据结构是众多 IT 公司评判面试人员能力高低的重要工具。 同任何一门编程语言相比,数据结构确实是晦涩难懂的。举个简单的例子,众多学习数据结构的读者中,可能很多人都能快速学会链表、哈希表、二叉树,还能熟练运用大部分的查找算法和排序算法,但能玩转路径规划、字符串匹配、动态规则等复杂问题的人,却凤毛麟角。 因此,要想学好数据结构,不仅要求学员具备良好的编程基础,还必须具有较强的逻辑分析能力和理解能力,甚至还需要具有一定的空间想象能力,可以这么说,能玩转数据结构的人,其综合实力往往都不差。很多大的互联网公司,更看重的往往不是你精通多少种编程语言,而是综合能力,更确切地说是解决问题的能力。 有些读者可能会问,类似 C++ 可以使用 STL 标准库,Python 代码可以使用 Collections 模块等,很多编程语言都可以使用相应的集成数据结构的框架或者模块,直接拿来用不就可以了吗? 事实上,很多在职程序员在开发过程中,都会套用现有的一些集成数据结构的模块或者框架。要知道,适当的使用是可取的,但不能完全依赖,否则知其然而不知其所以然,即便完成再多的项目,也无非是他人代码的搬运工,个人能力很快会进入瓶颈期,再无提升的空间。
3、程序性能好坏的评判标准
对于如何评判一个人编程能力的强弱,不同的人有不同的标准,或许是看中他编写代码的可读性,扩展性、是否健壮等等。我认为,代码执行性能的好坏无疑能成为众多评判标准中的一个。而想编写出性能高的代码,前提是必须知道如何评判代码的性能,这就不得不使用数据结构中评判代码执行性能的时间复杂性和空间复杂度。 对于某些在职的程序员来说,如果觉得数据结构无用,更多可能是因为你接触的都是一些用户量很少、需要处理的数据量也很少的小项目,实际开发中更注重实现具体的功能,产品的性能要求并非那么苛刻。反之,如果你身处像 BAT 这样的大公司,所开发产品的用户量往往是千万级别甚至亿级别,需要处理的数据量也往往是 TB 甚至 PB 级别,这时产品的性能将是首要考虑的因素,而数据结构和算法的意义将会彻底凸显出来。
别忘了,数据结构也是很多大厂IT公司选拔人才的重要标准,比如华为、腾讯、阿里、百度、京东、头条、字节跳动等等。
各位同学们有需要提高编程技术水平、编程思维能力和动手开发实战能力。比如:考国家二级C语言、计算机考研C和数据结构、Windows C/C++开发工程师、计算机竞赛、蓝桥杯竞赛等等。现已推出最新课程,大家可以根据自己情况,选择适合自己的课程哦!加油!加油!加油!
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/96199.html