C语言作为计算机编程的基础语言之一,无论是初学者还是经验丰富的开发者,都会接触到各种经典的编程题目。无论你是准备通过面试测试,还是希望通过不断地练习来提高编程能力,解决经典的C语言编程题都能够有效地帮助你掌握语言的基础、算法设计和优化技巧。
1.求素数的个数

素数是一个大多数编程面试和考试中都会出现的经典问题。素数是指只能被1和它自身整除的数。在C语言中实现求素数的算法,不仅考察了你对循环和条件语句的理解,还涉及了数学上的基础知识。
输入一个正整数n,求出小于或等于n的素数个数。
题目解析:
我们要理解如何判断一个数是否是素数。判断一个数是否是素数,可以使用从2到该数的平方根的所有整数进行除法运算,若有整除的结果则说明该数不是素数。为了提高效率,通常使用“埃拉托斯特尼筛法”,即通过标记合数,最终留下的就是素数。
代码实现:
#include
#include
intisPrime(intnum){
if(num<=1)return0;
for(inti=2;i<=sqrt(num);i++){
if(num%i==0){
return0;//不是素数
}
}
return1;//是素数
}
intmain(){
intn,count=0;
printf("请输入一个正整数n:");
scanf("%d",&n);
for(inti=2;i<=n;i++){
if(isPrime(i)){
count++;
}
}
printf("小于等于%d的素数个数是:%d\n",n,count);
return0;
}
分析:
通过上述代码,我们不仅解决了判断素数的问题,还实现了一个函数isPrime来进行素数判断。对于较大的数字,可以进一步优化算法,使用“筛法”来计算所有小于n的素数。
2.字符串反转
字符串反转是另一个常见的C语言编程题,常用于考察对字符串操作的理解。它要求你通过编程技术将一个字符串的字符顺序反转。
输入一个字符串,将字符串中的字符顺序反转输出。
题目解析:
解决此题需要掌握如何遍历和修改字符串中的字符。在C语言中,字符串是由字符数组表示的,因此可以通过指针操作或者数组下标操作来修改字符的位置。
代码实现:
#include
#include
voidreverseString(charstr[]){
intlength=strlen(str);
intleft=0,right=length-1;
while(leftchartemp=str[left];str[left]=str[right];str[right]=temp;left++;right--;}}intmain(){charstr[100];printf("请输入一个字符串:");fgets(str,sizeof(str),stdin);str[strcspn(str,"\n")]='\0';//去掉换行符reverseString(str);printf("反转后的字符串是:%s\n",str);return0;}分析:在此题中,reverseString函数通过双指针交换字符串两端的字符,逐步将字符串反转。fgets用于读取输入字符串,strcspn用于去除末尾的换行符。3.斐波那契数列斐波那契数列是数学中的经典问题,也是编程中的经典题目。该数列中的每一项是前两项的和,常用于测试递归和循环的应用。给定一个整数n,求出斐波那契数列的第n项。题目解析:斐波那契数列的定义为:F(0)=0,F(1)=1,对于n>=2,F(n)=F(n-1)+F(n-2)。可以使用递归或者迭代来解决这个问题。代码实现:#includeintfibonacci(intn){if(n==0)return0;if(n==1)return1;returnfibonacci(n-1)+fibonacci(n-2);}intmain(){intn;printf("请输入n:");scanf("%d",&n);printf("斐波那契数列的第%d项是:%d\n",n,fibonacci(n));return0;}分析:虽然递归实现简单直接,但时间复杂度较高,尤其是n较大时会导致重复计算。如果要优化,可以使用动态规划来减少重复计算。4.数组去重数组去重问题考察的是如何有效地从一个数组中删除重复元素。C语言没有像其他高级语言一样内置去重功能,因此需要通过算法手动实现。给定一个整数数组,去除重复的元素,并输出去重后的数组。题目解析:解决该问题可以利用哈希表来判断元素是否出现过,从而达到去重的效果。由于C语言没有直接的哈希表支持,我们可以通过排序后遍历的方式来去重。代码实现:#include#includeintcompare(constvoid*a,constvoid*b){return(*(int*)a-*(int*)b);}voidremoveDuplicates(intarr[],int*size){qsort(arr,*size,sizeof(int),compare);//排序intnewSize=1;for(inti=1;i<*size;i++){if(arr[i]!=arr[i-1]){arr[newSize++]=arr[i];}}*size=newSize;//更新新数组的大小}intmain(){intarr[]={3,1,2,3,4,1,2};intsize=sizeof(arr)/sizeof(arr[0]);removeDuplicates(arr,&size);printf("去重后的数组是:");for(inti=0;iprintf("%d",arr[i]);}printf("\n");return0;}分析:qsort函数用于对数组进行排序,然后通过遍历数组检查相邻元素是否相同,从而删除重复的元素。这是一种简单而高效的方法,时间复杂度主要取决于排序算法。5.判断回文字符串回文字符串是指从前往后读和从后往前读都相同的字符串。例如,“madam”是回文字符串。判断一个字符串是否是回文字符串是经典的面试题目。给定一个字符串,判断该字符串是否为回文。题目解析:判断回文的基本思路是:从两端开始,逐一比较字符是否相等。如果两端字符相等,则继续比较下一个字符;如果不相等,则不是回文。代码实现:#include#include#includeintisPalindrome(charstr[]){intleft=0,right=strlen(str)-1;while(leftif(tolower(str[left])!=tolower(str[right])){return0;//不是回文}left++;right--;}return1;//是回文}intmain(){charstr[100];printf("请输入一个字符串:");fgets(str,sizeof(str),stdin);str[strcspn(str,"\n")]='\0';//去掉换行符if(isPalindrome(str)){printf("该字符串是回文\n");}else{printf("该字符串不是回文\n");}return0;}分析:isPalindrome函数通过双指针从两端开始向中间移动,逐步判断字符是否相同。为了忽略大小写,使用了tolower函数。6.最长公共子串最长公共子串问题是字符串算法中的经典问题,通常用于测试对动态规划和字符串匹配的掌握程度。给定两个字符串,求它们的最长公共子串。题目解析:可以利用动态规划来解决该问题,创建一个二维数组来记录公共子串的长度,最终找到最大值。代码实现:#include#includeintlongestCommonSubstring(charstr1[],charstr2[]){intlen1=strlen(str1),len2=strlen(str2);intdp[len1+1][len2+1];intmaxLength=0;for(inti=0;i<=len1;i++){for(intj=0;j<=len2;j++){if(i==0||j==0){dp[i][j]=0;}elseif(str1[i-1]==str2[j-1]){dp[i][j]=dp[i-1][j-1]+1;if(dp[i][j]>maxLength){maxLength=dp[i][j];}}else{dp[i][j]=0;}}}returnmaxLength;}intmain(){charstr1[]="abcdef";charstr2[]="zbcdf";intlength=longestCommonSubstring(str1,str2);printf("最长公共子串的长度是:%d\n",length);return0;}分析:通过二维数组dp记录子串匹配情况,最终找到最长公共子串的长度。以上就是C语言中的一些经典编程题,解决这些问题不仅能够帮助你巩固基础知识,还能够提升你的编程能力和解决实际问题的能力。