一.计算一个3*3的整形矩阵对角线元素之和(二维数组)
1.一开始就设好的
#include <stdio.h>
int main()
{
int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};//自己设出来的矩阵
int sum=0;
int i=0;//要先声明变量
for(i=0;i<3;i++)
{//注意括号
sum +=arr[i][i];//注意是arr[i][i],不是[i][i],这里是一个索引值
} printf("%d\n",sum); //如果放在循环里面就会产生每次计算的值1 6 15 ,循环外只会打印15
return 0;
2需要输入的
#include <stdio.h>
int main() {
int arr[3][3];
int sum = 0;
int i, j;
// 提示用户输入完整的3x3矩阵
printf("请输入一个3x3矩阵的元素:\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
scanf("%d", &arr[i][j]); // 读取用户输入的矩阵元素
}
}//注意这里有两个循环,因为是二维数组
// 下面这个循环用来计算对角线元素的和
for (i = 0; i < 3; i++) {
sum += arr[i][i]; // 累加对角线元素
}
// 打印对角线元素的和
printf("对角线元素之和为: %d\n", sum);
return 0;
}
注意:如果你上面不写两个循环,只用下面的话,你输入矩阵的值他只会选前三个当作对角线的值
二排序问题
1.找出n个数字中最大最小并输出
#include <stdio.h>
int main() {
int n, arr[10000];
scanf("%d", &n); // 读取数组元素的数量
// 读取数组的第一个元素,并初始化max和min
scanf("%d", &arr[0]);
int max = arr[0];
int min = arr[0];
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]); // 读取数组的下一个元素
if (arr[i] < min) {
min = arr[i]; // 更新最小值
}
if (arr[i] > max) {
max = arr[i]; // 更新最大值
}
}
// 打印数组的所有元素
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// 打印最大值和最小值
printf("Max: %d\n", max);
printf("Min: %d\n", min);
return 0;
}
2.给n个数对这些数排序
#include <stdio.h>
int main() {
int n, arr[1000];
scanf("%d", &n);
//读取用户输入的 n 个整数,并将它们存储在数组 arr 中。
//循环从索引 0 开始,一直到 n-1(因为数组索引是从 0 开始的)。
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
int min_idx = 0; // 假设第一个元素是最小的
for (int i = 1; i < n; i++) { // 从第二个元素开始寻找最小值
if (arr[i] < arr[min_idx]) {
min_idx = i; // 更新最小值的索引
}
}
// 交换第一个元素和找到的最小值
int temp = arr[0];
arr[0] = arr[min_idx];
arr[min_idx] = temp;
// 打印数组
for (int i = 0; i < n; i++) {
printf("%d\n", arr[i]);
}
return 0;
}
3. 二分查找(在 有序!数组中查找某个数)
计算中间元素下标,左右下标----->中间元素下标
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
int sz = sizeof(arr) / sizeof(arr[0]) - 1; // 计算数组 arr 的最后一个元素的索引
int left = 0;
int right = sz;//不用减一
//因为我们在计算 mid 时已经通过 mid = left + (right - left) / 2 避免了下标越界的问题。
int key = 7; // 要找的元素是7
int mid;
int find = 0; // 假设开始没有找到
while (left <= right) {
mid = left + (right - left) / 2;
// 避免溢出!
//如果写成mid = (left+right)/2;有溢出风险且上面right需要减一;
if (arr[mid] < key) {
left = mid + 1;
} else if (arr[mid] > key) {
right = mid - 1;
} else {
find = 1; // 找到了
break;
}
}
if (find) {//非零为真
printf("找到了,下标为%d", mid);
} else {
printf("没找到\n");
}
return 0;
}
4.给一串数字以0结束,倒着输出 但不输出0
#include <stdio.h>
int main() {
int arr[1000]; // 假设最多读取1000个整数
int i = 0; // 数组索引
int n;
// 读取一行内以空格分隔的整数,直到遇到00
while (1) {
scanf("%d", &n);
if (n == 0) break; // 如果输入0,则结束输入
arr[i++] = n; // 将读取的整数存储到数组中
}
// 反向打印这一串整数
for (int j = i - 1; j >= 0; j--) {
printf("%d ", arr[j]);
}
printf("\n");
return 0;
}
5.冒泡排序
#include <stdio.h>
int main()
{
int arr[10]={10,9,8,7,6,5,4,3,2,1};
for(int i=0;i<9;i++)
{
///外层 for 循环控制排序的轮数,因为数组有10个元素,所以需要进行9轮比较才能完成排序
for(int j=0;j<10-1-i;j++)
//内层 for 循环用于在每轮排序中比较相邻的元素。
//10-1-i 表示每轮排序中,比较的次数会随着排序的进行而减少,因为数组后面的元素已经排好序了。
{
if(arr[j]>arr[j+1])
//如果当前元素 arr[j] 大于它后面的元素 arr[j+1],则进入 if 语句块。
{
//交换两个元素的位置,使得较小的元素移到数组的前面,较大的元素排在后面。
int t=arr[j+1];
arr[j+1]=arr[j];
arr[j]=t;
}
}
}
for(int i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;//如果要打印一堆数组,则要重新写一个for循环
}
三.计算数列之和
计算 1+2+3+⋯+(𝑛−1)+𝑛1+2+3+⋯+(n−1)+n 的值 ,输入n,输出和的值
#include <stdio.h>
int main() {
int arr[1000];
int n;
int sum = 0; // 初始化累加和为0
// 读取用户输入的n值
scanf("%d", &n);
// 检查n是否小于等于数组的长度1000
if (n <= 0 || n > 1000) {
printf("输入的数字不满足条件,应为1至1000之间的整数。\n");
return 1;
}
// 初始化数组并计算累加和
for (int i = 0; i < n; i++) {
arr[i] = i + 1; // 将数组的每个元素设置为1到n,
//注意:
1.数组元素初始化:代码试图将每个数组元素 arr[i] 设置为 n 的值,但这不是求和的目的。如果我们想要计算从 1 到 n 的和,我们应该将每个数组元素初始化为它自己的索引值 i。
2.求和逻辑:累加和 sum 应该基于数组元素的实际值进行累加,而不是简单地将 n 重复相加。
sum += arr[i]; // 累加和加上当前元素的值
}
// 打印最终的和
printf("%d\n", sum);//放循环外面是因为输出一个值
return 0;
}
关于printf什么时候放外面什么时候放里面问题
在C语言中,`printf` 函数用于输出数据到标准输出设备,通常是你的显示器或终端窗口。`printf` 的使用位置取决于你想要实现的程序逻辑和输出格式。以下是一些常见的使用场景:
1. **循环外部**:当你想要在循环执行完毕后输出最终结果时,将 `printf` 放在循环外部。
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i;
}
printf("Sum is: %d\n", sum); // 循环结束后打印总和
```
2. **循环内部**:如果你需要在每次循环迭代时都打印信息,将 `printf` 放在循环内部
for (int i = 0; i < n; i++) {
printf("Value of i: %d\n", i); // 每次迭代都打印当前的 i 值
}
```
3. **条件语句中**:当输出依赖于某些条件是否满足时,可以将 `printf` 放在 `if` 或 `else` 语句块中。
if (condition) {
printf("Condition is met.\n");
} else {
printf("Condition is not met.\n");
}
4. **函数调用后**:在调用一个函数并希望立即显示返回结果时,可以将 `printf` 放在函数调用后。
int result = someFunction();
printf("Result of function: %d\n", result);
```
5. **程序开始和结束**:通常在 `main` 函数的开始处打印欢迎信息,在程序结束前打印结束信息或最终结果。
printf("Program starts.\n");
// ... 程序代码 ...
printf("Program ends.\n");
```
6. **错误处理**:在检测到错误时,`printf` 用于输出错误信息。
if (errorCondition) {
printf("Error: Something went wrong!\n");
return 1; // 非零值通常表示程序出错
}
7. **格式化输出**:当需要格式化输出数据,如对齐、指定小数点后位数等,`printf` 可以与格式化输出一同使用
printf("Name: %s, Age: %d\n", name, age);
```
四. 矩阵转置(二维数组)
#include <stdio.h>
int main() {
int matrix[3][4];
int i, j;
// 填充矩阵
for(i = 0; i < 3; i++) {
for(j = 0; j < 4; j++) {
scanf("%d", &matrix[i][j]);
}
}
// 交换矩阵的行和列
for(i = 0; i < 3; i++) {
for(j = 0; j < i; j++) { // 注意这里 j < i,避免交换对角线上的元素和自己
// 交换 matrix[i][j] 和 matrix[j][i]
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// 打印修改后的矩阵
for(i = 0; i < 3; i++) {
for(j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
五.冰雹猜想
给出一个正整数 𝑛n,然后对这个数字一直进行下面的操作:如果这个数字是奇数,那么将其乘 33 再加 11,否则除以 22。经过若干次循环后,最终都会回到 11。经过验证很大的数字(7×10117×1011)都可以按照这样的方式比变成 11,所以被称为“冰雹猜想”。例如当 𝑛n 是 2020,变化的过程是 20→10→5→16→8→4→2→120→10→5→16→8→4→2→1。
#include <stdio.h>
int main() {
int arr[1000];
int i = 0; // 初始化数组索引
int n;
scanf("%d", &n);
while (n != 1) { // 循环直到n变为1
arr[i++] = n; // 存储当前的n值,并增加索引
if (n % 2 == 0) {
n = n / 2; // 如果n是偶数,除以2
} else {
n = n * 3 + 1; // 如果n是奇数,乘以3再加1
}
}
arr[i++] = n; // 将1加入数组,把n赋值给arr[i]自增,本来是零然后加一,变成1,在循环外
//或者printf("1 ");也可以,注意有空格
// 反向打印数组
for (int j = i - 1; j >= 0; j--) {
printf("%d ",arr[j]);//这里有空格别忘了,在引号里面
//这个下面的不写也行
if (j > 0) { // 除了最后一个数字外,每个数字后加空格
printf(" ");
}
}
printf("\n"); // 打印换行符
return 0;
}
六杨辉三角
给出 𝑛(𝑛≤20),输出杨辉三角的前 𝑛 行。
#include <stdio.h>
int main()
{
int n,matrix[100][100]={0};//每行最多有20个数字,注意要初始化
scanf("%d",&n);
matrix[1][1]=1;
//初始化杨辉三角的顶部元素为1,所以下面的i就从2开始而不是零注意变通
for(int i=2;i<=n;i++){
//这个循环用于生成杨辉三角的第2行到第 n 行。这里使用 <= n 是正确的,因为我们需要包含第 n 行。
for(int j=1;j<=i;j++){
//内层循环用于生成每一行的元素。j <= i 是正确的,因为第 i 行有 i 个元素,包括两端的1
matrix[i][j]=matrix[i-1][j-1]+matrix[i-1][j];
}
}
//这两个嵌套的 for 循环用于计算杨辉三角的每一行和每一列的值。外层循环 i 从2遍历到 n,表示杨辉三角的第2行到第 n 行。内层循环 j 从1遍历到 i,表示每一行的第1个到第 i 个元素。matrix[i][j] 的值是其正上方两个数的和,即 matrix[i - 1][j - 1] 和 matrix[i - 1][j]。
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){//注意j初始值即循环条件
printf("%d ",matrix[i][j]);
}//注意要有大括号
printf("\n");//注意这个在小循环外
}
//这两个嵌套的 for 循环用于打印杨辉三角。外层循环 i 同样从1遍历到 n,内层循环 j 从1遍历到 i。printf 函数用于打印 matrix[i][j] 的值,并且每个数字后面有一个空格。每打印完一行后,使用 printf("\n"); 换行。
return 0;
}
七.涉及字符串
1.输入一行,一个字符串
输出一个字符串,即将原字符串中的所有小写字母转化为大写字母。
#include <stdio.h>
int main()
{
char str[127];//声明一个字符数组,为啥是127?
//选择127是因为在ASCII编码中,最大值是127,
//这样可以确保数组能够存储一个完整的ASCII字符集,包括所有小写字母和大写字母。
scanf("%s",str);//为什么没有&?数组名作为指针
char *p=str;
while(*p!='\0'){
//这个 while 循环会一直执行,直到遇到字符串的结束标志 '\0'
if('a'<=*p&&*p<='z'){
//'a' <= *p:这个条件检查 p 指向的字符是否大于或等于字符 'a'。在ASCII码表中,小写字母从 'a' (ASCII码 97) 开始。
// *p <= 'z':这个条件检查 p 指向的字符是否小于或等于字符 'z'。在ASCII码表中,小写字母在 'z' (ASCII码 122) 结束。
printf("%c",*p-'a'+'A');
}
else
{ printf("%c",*p);
}
p++;//在循环的每次迭代结束时,指针 p 会增加,移动到下一个字符
}
return 0;
}
2.蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 n 位形成的。z
的下一个字母是 a
,如此循环。他现在找到了移动前的原文字符串及 n,请你求出密码。
Input
第一行:n。第二行:未移动前的一串字母。
Output
第一行,是此蒟蒻的密码。
错误代码:
#include <stdio.h>
int main()
{
char str[127];//为什么这里也是127,写更大一点可以吗
scanf("%s",str);
char *p=str;
int n;
scanf("%d",&n);
while(*p!='\0'){
int c=*p+n;
if(c>'z')
{ c-=26;
printf("%c",c);
p++;}
}
return 0;
}
错误原因:
1.先输入n,后输入字符不符合要求
2.if括号那里有问题
正确代码:
#include <stdio.h>
int main()
{
char str[127];//为什么这里也是127,写更大一点可以吗
char *p=str;
int n;
scanf("%d",&n);
scanf("%s",str);
while(*p!='\0'){
int c=*p+n;
if(c>'z')
c-=26;
printf("%c",c);//if这里不加括号表示if只执行c-=26;
/*也可以写成 if(c>'z')
{ c-=26;
printf("%c",c);
}
else{
printf("%c",c);
}
p++;注意p++在if外
}*/
p++;}
return 0;
}