1.斐波那契数列
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三 个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 兔子的规律为数列1,1,2,3,5,8,13,21
主要涉及知识点:循环选择的嵌套、输出的格式控制(可转变方式用数组、递归的方式实现)
/*控制输出,每行四个*/
#include<stdio.h>
int main() {
int num[20] = {0};
num[1] = 1;
num[2] = 1;
for (int i = 2; i < 20; i++) {
num[i] = num[i - 1] + num[i - 2];
}
//for (int i = 0; i < 20; i++) {
// printf("第%d个月有%d对兔子,有%d只兔子\n", i+1, num[i], 2 * num[i]);
//}
for (int i = 0; i < 20; i++) {
printf("%6d", num[i]);//"%6d"表示输出长度,在左填空格够6位
/*如果想在右填空格;用‘-’符号修饰符
* printf("%-6d",num[i]);
* 祥符号控制符见《C语言程序设计基础(例题)》
*/
if (i % 4 == 0) { //%取余
printf("\n");
}
}
return 0;
}
2.乘法口诀表
输出9*9口诀。共9行9列,i 控制行,j 控制列。
主要涉及知识点:循环嵌套、输出的格式控制
#include<stdio.h>
int main() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d * %d = %-4d", i, j, i * j);//"%-4d"见上一题
}
printf("\n");
}
return 0;
}
3.数组插数再排序
已知数组a中的元素已按由小到大顺序排列,以下程序的功能是将输入的一个数插入数 组a中,插入后,数组a中的元素仍然由小到大顺序排列
主要涉及知识点:一维数组、插入算法、数组元素的移动
#include<stdio.h>
int main() {
int num1[9] = { 1,2,3,4,5,6,7,8,9, };
int num2[9 + 1];
int n;
for (int i = 0; i < 9; i++) {
printf("%-3d", num1[i]);
}
printf("\n输入一个数\n");
scanf("%d", &n);
for (int i = 0; i < 9; i++) {
if (!(n > num1[i])) {
int temp = num1[i];
num2[i+1] = temp;
n = i;
break;
}
}
for (int i = 0; i < 9 + 1; i++) {
if (i <= n) {
num2[i] = num1[i];
}
if (i > n + 1) {
num2[i] = num1[i - 1];
}
}
for (int i = 0; i < 9 + 1; i++) {
printf("%-3d", num2[i]);
}
return 0;
}
4.矩阵的旋转
下面程序的功能是将一个4×4的数组进行逆时针旋转90度后输出,要求原始数组的 数据随机输入,新数组以4行4列的方式输出。
主要涉及知识点:二维数组的输入及输出、循环嵌套与二维数组的结合、输出的格式控制
#include<stdio.h>
int main() {
int num1[4][4], num2[4][4];
printf("请输入16个数字:\n");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
scanf_s("%d",&num1[i][j]);
num2[3 - j][i] = num1[i][j];
}
printf("\n");
}
printf("转置前:\n");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%d", num1[i][j]);
}
printf("\n");
}
printf("转置后:\n");
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%d", num2[i][j]);
}
printf("\n");
}
return 0;
}
5.杨辉三角形
编程打印直角杨辉三角形
主要涉及知识点:二维数组的输入及输出、循环嵌套与二维数组的结合、输出的格式控制
#include<stdio.h>
int main() {
int num[10][10] = {0};
for (int i = 0; i < 10; i++) {
num[i][0] = 1;
}
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
num[i][j] = num[i - 1][j] + num[i - 1][j - 1];
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j <= i; j++) {
printf("%-5d", num[i][j]);
}
printf("\n");
}
return 0;
}
6.素数
输入两个正整数m,n(1<=m,n<=500)统计并输出m和n之间的素数个数及这些素数的和。
#include <stdio.h>
#include<math.h>
int main(){
int count, i, j, m, n, sum;
scanf_s("%d%d", &m, &n);
count = 0,sum = 0;
for (int i = m; i <= n; i++) {
for (int j = 2; j <= sqrt(i); j++) {
if (i % j == 0)
break;
if (j == sqrt(i)) {
count++;
sum += i;
}
}
}
if (m == 2) {
count++;
sum += 2;
}
printf("%-4d%-4d", count, sum);
return 0;
}
7.回文字符串
输入一个字符串,判断其是否为回文。回文字符串是指从左到右读和从右到左读完全 相同的字符串。
主要涉及知识点:字符数组的输入输出,及相应的处理
#include <stdio.h>
#include <string.h>
int main(){
char str[100];
int n;
printf("请输入字符串\n");
fgets(str,sizeof(str)-1,stdin);//fgets与gets
/*
gets从标准输入读取字符,直到遇到换行符\n,或文件结束符EOF
会自动将这些符号置换为字符串结束符\0;
但是gets不会检查缓冲区是否足够容纳,导致溢出
*/
/*
fgets的格式为fgets(buffer,size,stream)
buffer是存储字符串的字符数组,
size是允许读取的最大字符数,达到size-1是自动填\0;
stream输入流,stdin是标准输入
*/
n = strlen(str)-1;//strlen与sizeof
/*
strlen计算的字符串《长度》不含\0
sizeof用于获取数据类型或变量的《字节数》
*/
for (int i = 0; i < n; i++) {
if (str[i] != str[n - 1 - i]) {
printf("不是回文串");
break;
}
}
for (int i = 0; i < n; i++) {
if (str[i] != str[n - 1 - i])
break;
if (i >= n - 1 - i) {
printf("是回文串");
break;
}
}
return 0;
}
用了两个相同的for循环,可简化
#include <stdio.h>
#include <string.h>
int main(){
char str[100];
int n;
printf("请输入字符串\n");
fgets(str,sizeof(str)-1,stdin);//fgets与gets
n = strlen(str)-1;//strlen与sizeof
for (int i = 0; i < n; i++) {
if (str[i] != str[n - 1 - i]) {
printf("不是回文串");
return 0;
if (i >= n - 1 - i) {
printf("是回文串");
return 0;
}
}
return 0;
}
8.删除指定字符
下面程序的功能是从字符数组a中删除存放在其中的字符c。
主要涉及知识点:字符数组的输入输出,及相应的处理
#include <stdio.h>
#include <string.h>
int main(){
char str[100];
char c;
printf("输入一个字符串\n");
fgets(str, 100, stdin);
printf("\n再输入一个字符\n");
c = getchar();
//scanf_s("%c", &c);//%c
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == c) {
for (int k = i; str[k] != '\n'; k++) {
str[k] = str[k + 1];
}
}
}
//str[]!='\n'
printf("%s", str);//%s
return 0;
}
9.字符串反序输出
完善程序,实现将输入的字符串反序输出,如输入windows 输出swodniw。
主要涉及知识点:字符串的输入输出、字符串处理函数
#include<stdio.h>
#include<string.h>
int main() {
char ch[100];
printf("Enter a string\n");
fgets(ch, sizeof(ch)-1, stdin);//fgets
/*
如果使用scanf,可使用以下方式
scanf("%99s",ch);
*/
size_t k = strlen(ch)-1;
for (int i = 0; i <= k/2; i++) {
char tream = ch[i];
ch[i] = ch[k - i];
ch[k - i] = tream;
}
printf("%s\n", ch);
return 0;
}
10.计算π的近似值
编写函数countpi,
利用公式
计算π的近似值,当某一项的值小于10-5时,认为达到精度要求,请完善函数。
#include<stdio.h>
double countpi() {
double term = 1;
double pi_half = 1;
int n = 1;
while (term >= 1e-5) {
n++;
term *= (double)(n - 1) / (2 * n - 1);//(doouble)使原本的整数改为浮点数
pi_half += term;
}
return 2 * pi_half;
}
int main() {
printf("Π的近似值:%lf\n", countpi());
return 0;
}
11.冒泡,选择排序
冒泡排序,从小到大,排序后结果输出到屏幕(使用函数)
主要涉及知识点:函数、排序算法、循环嵌套
#include<stdio.h>
void input(int num[], int n);
void swap(int* a, int* b);
void output(int num[], int n);
void Bubble_Sort(int num[], int n);//冒泡排序
void Selection_Sort(int num[], int n);//选择排序
int main() {
int n;
scanf("%d", &n);
int num[n];//最新的C语言和C++都支持这种写法哦!!
input(num, n);
Bubble_Sort(num, n);
Selection_Sort(num, n);
return 0;
}
void input(int num[], int n) {
for (int i = 0; i < n; i++) {
scanf("%d", &num[i]);
}
output(num, n);
}
void swap(int* a, int* b) {
int term = *b;
*b = *a;
*a = term;
}
void output(int num[], int n) {
for (int i = 0; i < n; i++) {
printf("%-4d", num[i]);
}
printf("\n");
}
void Bubble_Sort(int num[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n - i; j++) {
if (num[j] > num[j + 1]) {
swap(&num[j], &num[j + i]);
}
}
}
output(num, n);
}
void Selection_Sort(int num[], int n) {
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i+1; j < n - i; j++) {
if (num[j] < num[min]) {
swap(&j, &min);
}
}
}
output(num, n);
}
12.字符串查找
在一个字串s1中查找一子串s2,若存在则返回子串在主串中的起始位置 ,不存在则返回-1。
主要涉及知识点:字符数组、查找算法、字符串处理函数
#include <stdio.h>
#include <string.h>
int findSubstring(char *s1, char *s2) {
//int len1 = strlen(s1);
//int len2 = strlen(s2);//strlen
/*
strlen遇到‘\0'会停止计数,但是不会计算空字符如‘\0’;但是换行符‘\n’是一个字符。
所以直接读取是不对的
把换行符替换为’\0‘*/
/* 如下* /
//s1[strcspn(s1, "\n")] = '\0';//strcspn的作用是得出si这个字符串中第一次出现“\n"的位置数
//s2[strcspn(s2, "\n")] = '\0';
/*或者如下*/
int len1 = strlen(s1);
int len2 = strlen(s2)-1;
if (len2 > len1) {
return -1; // 子串长度大于主串,不可能存在
}
for (int i = 0; i <= len1 - len2; i++) {
int j;
for (j = 0; j < len2; j++) {
if (s1[i + j] != s2[j]) {
break; // 当前字符不匹配,退出内层循环
}
}
if (j == len2) {
return i; // 子串完全匹配,返回起始位置
}
}
return -1; // 未找到子串
}
int main() {
char s1[100];
char s2[100];
fgets(s1, 30, stdin);
fgets(s2, 30, stdin);//fgets
/*
fgets函数会读取换行符‘\n’
*/
int result = findSubstring(s1, s2);
if (result == -1) {
printf("子串不存在于主串中\n");
}
else {
printf("子串在主串中的起始位置是: %d\n", result);
}
return 0;
}
/*strcspn 是 C 语言标准库中的一个字符串函数,它的作用是在一个字符串中查找另一个字符串中任意字符首次出现的位置,并返回这个位置之前的字符个数。
size_t strcspn(const char *str1, const char *str2);
str1:要搜索的字符串。
str2:包含要搜索的字符的字符串。
返回 str1 中从起始位置开始,到第一个包含 str2 中任意字符的位置之间的字符个数。如果 str1 中不存在 str2 中的字符,则返回 str1 的长度。*/
13.替换算法
编写函数replace(char *s,char c1,char c2)实现将s所指向的字符串中所有字符c1用c2 替换,字符串、字符c1和c2均在主函数中输入,将原始字符串和替换后的字符串显示在屏 幕上
主要涉及知识点:替换算法、函数、字符数组、文件操作
#include<stdio.h>
#include<string.h>
// 函数声明和定义的返回类型
char* string(char* str, char a, char b);
int main() {
char a, b;
char str[100];
printf("输入字符串str\n");
fgets(str, 99, stdin);
printf("%s\n", str);
printf("把字符串中的'x'改为'y';输入x和y\n");
a = getchar();
getchar();//除换行符
b = getchar();
printf("%s", string(str, a, b));
return 0;
}
// 函数返回类型为 char*
char* string(char* str, char a, char b) {
int length = strlen(str);
for (int i = 0; i < length; i++) {
if (str[i] == a) {
str[i] = b;
}
}
return str;
}
/*将返回类型声明为 char,实际上返回的是一个字符,而不是字符串。
这导致了编译错误,因为 char 类型无法表示字符串。
正确的返回类型应该是 char*,这样才能返回一个字符数组(即字符串)。
*/
14.指针变量输出结构体数组元素
用指针变量输出结构体数组元素。
主要涉及知识点:指针与结构体、结构体数组的赋值、输出
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int age;
float score;
};
int main() {
struct Student students[3] = {
{"Tom", 18, 90.5},
{"Bob", 19, 80.0},
{"Lily", 18, 95.0}
};//这只是初始化结构体的一种
struct Student* p = students;//由于 students 是一个数组,它的名称本身就代表了数组的首地址,因此可以直接将 students 赋值给 p。
/*struct Student* p 声明了一个名为 p 的指针,它指向 Student 结构体类型。*/
for (int i = 0; i < 3; i++) {
printf("Name: %s, Age: %d, Score: %.2f\n", (p + i)->name, (p + i)->age, (p + i)->score);
}//-> 是 C 语言中的一个指针操作符,用于访问结构体指针所指向的结构体成员。它的作用类似于点号(.)操作符,但它是用于指针的。
/*若不用指针
* for (int i =0; i < 3; i++) {
* printf("Name: %s,Age: %d, Score: %.2f\n",students[i].name,students[i].age,students[i].score);
* }
*/
return 0;
}
15.建立链表
建立一个有三个结点的简单链表:
主要涉及知识点:结构体、链表相关操作
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;
/*struct Node* head = NULL;:
声明一个指向 Node 结构体的指针 head,
并初始化为 NULL,表示链表的头节点为空。*/
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
/*使用 malloc 函数动态分配内存,
创建一个新的 Node 结构体,并将其地址赋值给 head 指针。*/
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
/*head->next = second; 和 second->next = third;
设置链表中节点的 next 指针,
使得 head 节点指向 second 节点,second 节点指向 third 节点。*/
third->data = 3;
third->next = NULL;
//将 third 节点的 next 指针设置为 NULL,表示链表的末尾。
struct Node* p = head;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;//将 p 指针移动到下一个节点。
}
printf("\n");
return 0;
}