11-小白学习中C代码存放

目录

1. 水仙花数

2. 冒泡排序法

3. 二维数组找最大数以及所在行列

4. 嵌套函数示例

5. 递归函数求学生年龄以及阶乘

6. 函数指针

7. 指针函数

8. 函数传值调用

9. 函数引值调用

10. 回调函数

11. 指针数组

12. 数组指针

13.二级指针

14. 对几个班级不同个数学生计算分数


1. 水仙花数

#指一个三位数,其各个数字立方和等于该数本身,例:153,13+53+33=15313+53+33=153

#include <stdio.h>
#include <math.h>

int main()

{
  for(int i = 100;i < 100000;i++){
    int wei = 0;// 位数
    int j = 0;//j:代替i,防止i变化
    j = i;
    //位数计算 
    while(j > 0){ //判断到最后
      wei++; 
      j /= 10; //除数运算例如123/10  得出12余3
    }
    //各 位值 计算
    int sum = 0; //sum:总和
    int num = 0; //num:代替i,防止i变化
    num = i;
    int mo = 0; //各位数值
    while(num > 0){
      mo = num%10; //取余获取位数值
      sum += pow(mo, wei);  //pow函数
      num /=10;
    }
    if(sum == i){
      printf("位数是%d,水仙花数是%d\n",wei,sum);
    }
  }

  return 0;
}
/*
{
   int num,i;
   for(i = 100;i <1000;i++){
     num = i;
     int sum = 0;
     while(num > 0){
       int mo = num%10;
       sum += mo*mo*mo;
       num /= 10;
     }
     if(sum == i){
       printf("水仙花数是%d\n",sum);
     }
   }

    return 0;
}
*/

2. 冒泡排序法

#通过多次遍历待排序的元素,每次比较相邻的两个元素,将较大(或较小)的元素交换至右侧,逐渐将最大(或最小)的元素“浮”到最右侧(或最左侧),直至所有元素都按序排列。

#include <stdio.h>

int main()

{
    int arr[] = {24,244,222,333,2};
    int i,j;
    int len;
    int tmp;
    len = sizeof(arr)/sizeof(arr[0]); //确认arr大小
    for(i = 0;i<len-1;i++){  
        for(j = 0;j < len -1-i;j++){  //选出最小的放在最后边
            if(arr[j] > arr[j+1]){
            tmp = arr[j+1];
            arr[j+1] = arr[j];
            arr[j] = tmp;
            }
        }
    }
    for(i = 0;i < len;i++){
        printf("%d ", arr[i]);
    }
    return 0;
}
//封装函数冒泡
#include <stdio.h>

void sort_arr(int arr[])
{
    int i,j,tmp;
    for(i = 0;i < 4;i++){
        for(j = 0;j < 5-i-1;j++){
            if(arr[j] > arr[j+1]){
                tmp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = tmp;
            }
        }
    }
    printf("排序后\n");
    for(i = 0;i < 5;i++){
        printf("%d ",arr[i]);
    }
}

int main()

{
    int arr[5];
    printf("please input 5 data\n");
    for(int i = 0;i < 5;i++){
        scanf("%d",&arr[i]);
    }
    printf("排序前\n");
    for(int i = 0;i < 5;i++){
    printf("%d ",arr[i]);
    }
    sort_arr(arr);
    return 0;
}

3. 二维数组找最大数以及所在行列

#由一维数组组成的数组

#include <stdio.h>

int main()

{
    int  arr[3][4] = {23,34,4,123,34,123,34,494,444,211,111,1}; //可以不写行,但是要写列
    int max = arr[0][0];
    int i,j;
    int max_i,max_j;
    for(i = 0;i < 3;i++){
        for(j = 0;j < 4;j++){
            if(arr[i][j] > max){
                max = arr[i][j];
                max_i = i;
                max_j = j;
            }
        }
    }
    for(i = 0;i < 3;i++){
        for(j = 0;j < 4;j++){
            printf("%d\t",arr[i][j]);
        }
        putchar('\n');
    }
    printf("最大数是%d,在第%d行,%d列",max,max_i+1,max_j+1);
    return 0;
}

4. 嵌套函数示例

#在一个函数内部定义另一个函数的情况

#include <stdio.h>

int getbig(int a,int b)
{
    int max;
    max = (a > b)?a:b;
    return max;
}

int getmax(int a,int b,int c,int d)
{
    int max;
    max = getbig(a,b);
    max = getbig(max,c);
    max = getbig(max,d);

    return max;
}

int main()

{
    int a,b,c,d,max;
    puts("输入四个数字");
    scanf("%d%d%d%d",&a,&b,&c,&d);
    max = getmax(a,b,c,d);
    printf("最大的数字是%d",max);
    return 0;
}

5. 递归函数求学生年龄以及阶乘

#指在函数内部调用自身的函数

#include <stdio.h>

int getfac(int fac); 
int getage(int num);    //函数声明 当函数体在调用前时需要,函数的声明最好在文件的顶部

int main()

{
    int age;
    int num;
    puts("你想知道第几个学生的年龄\n");
    scanf("%d",&num);
    age = getage(num);
    printf("他的年龄是%d\n",age);

    int fac;
    int number;
    puts("你想知道数字几的阶乘\n");
    scanf("%d",&number);
    fac = getfac(number);
    printf("阶乘结果是%d\n",fac);
    return 0;
}

int getage(int num){
    int data;
    if(num == 1){
        data = 10;
    }else {
        data = getage(num-1)+2;
    }
    return data;
}

int getfac(int number){
    int fac;
    if(number == 1){
        fac = 1;
    }else {
        fac = getfac(number-1)*number;
    }
    return fac;
}

6. 函数指针

#函数指针是指向函数的指针变量

#include <stdio.h>

// 定义一个函数max,返回x和y中的较大者
int max(int x, int y){
    return x > y ? x : y;
}

int main() {
    int (*p)(int, int) = &max; // p 是函数指针,指向具有相同参数和返回值的函数max
    int a, b, c, d;

    printf("输入三个数: ");  // 提示用户输入三个数

    // 从用户输入中获取三个整数值
    scanf("%d %d %d", &a, &b, &c);

    // 与直接调用函数等价,d = max(max(a, b), c)
    d = p(p(a, b), c);
    
    // 输出最大的数字
    printf("最大的数字是: %d\n", d);

    return 0;  // 程序正常终止
}

/*
详解每行代码:

1. #include <stdio.h>: 包含标准输入输出库的头文件。

2. int max(int x, int y): 定义了一个名为max的函数,它接受两个整型参数x和y,并返回较大的那个数。

3. int main() {: 主函数的开始。

4. int (*p)(int, int) = &max;: 声明了一个指向函数的指针p,并将其初始化为指向函数max的指针。&操作符用于获取函数的地址,但在这里可以省略,因为函数名本身就是函数的地址。

5. int a, b, c, d;: 声明了四个整型变量a、b、c、d。

6. printf("输入三个数: ");: 输出提示信息,提示用户输入三个数。

7. scanf("%d %d %d", &a, &b, &c);: 从用户输入中获取三个整数值,并分别赋值给变量a、b、c。

8. d = p(p(a, b), c);: 通过函数指针p调用max函数,计算a和b中的较大者,然后再计算出这个较大者和c中的较大者,并将结果赋值给d。

9. printf("最大的数字是: %d\n", d);: 输出变量d的值,即最大的数。

10. return 0;: 返回0,表示程序正常终止。
/*

7. 指针函数

#指返回指针的函数,也可以说是一个返回指针的函数指针

#include <stdio.h>
#include <stdlib.h>

//动态分配一个包含5个整数的数组,并对数组中的元素进行赋值,然后输出数组中的元素,并最后释放动态分配的内存
int* createArray(int size) {
    int* arr = (int*)malloc(size * sizeof(int));  // 使用malloc动态分配内存
    return arr;  // 返回指向动态分配数组的指针
}

int main() {
    int* arrayPtr;  // 声明一个指向整型的指针变量
    arrayPtr = createArray(5);  // 调用指针函数,获取指向动态分配数组的指针
    for (int i = 0; i < 5; i++) {
        arrayPtr[i] = i;  // 给动态分配的数组赋值
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", arrayPtr[i]);  // 输出数组中的元素
    }
    free(arrayPtr);  // 释放动态分配的内存
    return 0;
}
/*
详细解释:

1. #include <stdio.h> 和 #include <stdlib.h>: 这两行代码是预处理器指令,用于包含标准输入输出和动态内存分配函数的头文件。

2. int* createArray(int size) {: 这是一个函数定义,函数名为createArray,它接受一个整型参数size,并返回一个指向整型的指针。

3. int* arr = (int*)malloc(size * sizeof(int));: 在createArray函数中,使用malloc动态分配了一个大小为size个整型的内存块,并将其地址赋值给指针变量arr。函数malloc返回void类型的指针,因此需要进行类型转换为int类型。分配内存空间以存储整型数据。

4. return arr;: 函数createArray返回指向动态分配数组的指针arr。

5. int* arrayPtr;: 在main函数中声明一个指向整型的指针变量arrayPtr。

6. arrayPtr = createArray(5);: 调用createArray函数,获取指向动态分配数组的指针,并将其赋值给arrayPtr。

7. arrayPtr[i] = i;: 使用循环对动态分配的数组赋值。

8. printf("%d ", arrayPtr[i]);: 打印数组中的元素。

9. free(arrayPtr);: 释放动态分配的内存空间,以避免内存泄漏。

10. return 0;: 返回0,表示程序正常执行结束。

*/



8. 函数传值调用

#传递数值,调用的函数中数值交换不影响main中数值,单纯的传递两个数值

#include <stdio.h>
void exchage(int a,int b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
    printf("void_a的数值是%d 地址是%p    ",a,&a);
    printf("void_b的数值是%d 地址是%p    ",b,&b);
    putchar('\n');
}
int main()
{
    int a = 10;
    int b = 20;
    printf("传递数值前\n");
    printf("a的数值是%d 地址是%p    ",a,&a);
    printf("a的数值是%d 地址是%p    ",b,&b);
    putchar('\n');
    putchar('\n');
    exchage(a,b);
    putchar('\n');
    printf("传递数值后\n");
    printf("a的数值是%d 地址是%p    ",a,&a);
    printf("a的数值是%d 地址是%p    ",b,&b);
    return 0;
}

9. 函数引值调用

#传递main中变量地址,在调用函数中将地址内数值改变,从而改变了main中变量数值

#include <stdio.h>

void exchage(int *a,int *b)
{
    int tmp;
    tmp = *a; //更换了地址内的数值,地址不变
    *a = *b;
    *b = tmp;
    printf("void_a的数值是%d 地址是%p    ",*a,a);
    printf("void_b的数值是%d 地址是%p    ",*b,b);
    putchar('\n');
}

int main()
{
    int a = 30;
    int b = 20;
    printf("传递数值前:\n");
    printf("a的数值是%d 地址是%p    ",a,&a);
    printf("a的数值是%d 地址是%p    ",b,&b);
    putchar('\n');
    putchar('\n');
    exchage(&a,&b);
    putchar('\n');
    printf("传递数值后:\n");
    printf("a的数值是%d 地址是%p    ",a,&a);
    printf("a的数值是%d 地址是%p    ",b,&b);
    return 0;
}

10. 回调函数

#由别人的函数执行时调用你实现的函数

#include <stdio.h>
#include <stdlib.h>

void fill_arr(int *arr, size_t data, int (*getdata)(void))
//接受一个整型指针 arr,一个 size_t 类型的整数 data,和一个返回整型的
//  函数指针作为参数。函数通过调用传递的函数指针 getdata 来填充传入的整型数组 arr。
{
    for(size_t i = 0;i < data;i++)
        arr[i] = getdata();//调用传递的函数指针
}
//rand 是C标准库中的一个函数,用于生成一个介于0和RAND_MAX之间的伪随机整数。
int getdata(void)
{
    return rand();
}

int main()

{
    int arr[5];
    int i;

    fill_arr(arr,5,getdata);
    for(i = 0;i < 5;i++){
        printf("数值为%d\n",arr[i]);
    }

    return 0;
}

11. 指针数组

#是一个数组,其中每个元素都是指针

#include <stdio.h>

const int MAX = 3;

int main()

{
    int arr[] = {1,5,11};
    int i;

    for(i = 0;i < MAX;i++){
        printf("arr[%d]= %d\n",i,arr[i]);
    }

    int j;
    int *ptr[MAX];//int *ptr[MAX]; == int* ptr[MAX];
    int arr1[3] = {2,6,14};

    for(j = 0;j < MAX;j++){
        ptr[j] = &arr1[j]; //取arr地址赋值给指针ptr
    }
    for(j = 0;j < MAX;j++){
        printf("ptr[%d]= %d\n",j,*ptr[j]); //指针取值需要用*
    }
    return 0;
}

12. 数组指针

#数组指针本身是一个指针,指向整个数组,而不是数组中的单个元素。通常用于处理多维数组。

#include <stdio.h>

void printArray(int (*arrPtr)[3], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arrPtr[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int (*ptr)[3] = arr;

    printArray(ptr, 2);

    return 0;
}

13.二级指针

#指向指针的指针,常用于存储和管理不同类型或不同数量的数据结构。

#include <stdio.h>

int main()

{
    int a = 10;
    printf("a的数值是:%d,地址是:%p\n",a,&a);

    int *p;
    p = &a;
    printf("通过p取出的数值是:%d, p存放的地址是:%p, 存放p的地址是%p\n",*p,p,&p);

    int **p1;
    p1 = &p;
    printf("通过p1取出的数值是%d, p1指向p存放的地址是:%p, pi存放的地址是:%p, 存放p1的地址是%p\n",**p1,*p1,p1,&p1);

    return 0;
}

14. 对几个班级不同个数学生计算分数

#include <stdio.h>
#include <stdlib.h>
//函数声明
void assignment(int arrclass[],int num);
void printscore(int arr[],int num);
float getaverage(int arr[], int num);

void manage(int classnum)//班级循环计算函数
{
    for(int i = 0;i < classnum;i++){
        int numstudents; //学生个数
        printf("Enter the number of students in class %d: ", i + 1);//输入班级学生个数
        scanf("%d", &numstudents);
        //动态分配了numstudents * sizeof(int)个字节大小的内存空间,将其首地址赋值给指针变量arrclass
        //malloc函数返回的是void*类型的指针,(int *)是将指针强制转换为指向整型的指针
        int *arrclass = (int *)malloc(numstudents * sizeof(int));
        //处理内存分配失败
        if (arrclass == NULL) {
            printf("Memory allocation failed. Exiting...\n");
            exit(1);
        }
        printf("current calss number %d\n",i+1);
        assignment(arrclass,numstudents);//赋值
        printscore(arrclass,numstudents);//打印
        float average = getaverage(arrclass,numstudents);//计算平均分
        printf("classone %d average scora is %.2f\n",i+1,average);
        free(arrclass);  // 释放动态分配的内存
    }
}
void assignment(int arrclass[],int num)
{
    int i;
    printf("please input student score\n");
    for(i = 0;i < num; i++){
        scanf("%d",&arrclass[i]);
    }
}

void printscore(int arr[],int num)
{
    int i = 0;
    for(i =0;i < num;i++){
            printf("student(%d)score is %d \n",i,arr[i]);

    }
}

float getaverage(int arr[], int num)
{
    int sum = 0;
    float average;
    for(int i = 0;i < num;i++){
        sum += arr[i];
    }
    average = (float)sum/num;
    return average;
}
int main()

{
    int classnum;
    //确认有几个班级
    printf("Please enter the number of classes for which you want to calculate the average score \n");
    scanf("%d", &classnum);
    
    manage(classnum);
    return 0;
}




或者
#include <stdio.h>

int main() {
    int numClasses, numStudents, i, j;
    float average, sum;

    // 询问用户要处理几个班级的学生
    printf("请输入要处理几个班级的学生: ");
    scanf("%d", &numClasses);

    for (i = 1; i <= numClasses; i++) {
        sum = 0;  // 每个班级的学生成绩总和初始化为0

        // 获取当前班级有几个学生
        printf("请输入第%d个班级有几个学生: ", i);
        scanf("%d", &numStudents);

        printf("请输入第%d个班级%d位学生成绩:\n", i, numStudents);
        for (j = 1; j <= numStudents; j++) {
            float score;
            printf("请输入第%d位学生的成绩: ", j);
            scanf("%f", &score);
            sum += score;  // 累加成绩到总和
        }

        average = sum / numStudents;  // 计算平均成绩
        printf("第%d个班级的平均分为: %.2f\n", i, average);
    }

    return 0;
}

15. 选择排序

#在未排序的序列中选择最小(或最大)的元素,然后将其放置在已排序序列的末尾

#include <stdio.h>

void selectionSort(int arr[], int n) {
    int i, j, minIndex, temp;
    // 外层循环遍历数组
    for (i = 0; i < n - 1; i++) {
        // 假设当前位置是最小值的索引
        minIndex = i;
        // 在未排序部分中找到最小元素的索引
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // 将未排序部分中的最小元素与当前位置交换
        if (minIndex != i) {
            temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp; //保证每次i循环后 arr[i]是最小的
        }
    }
}

int main() {
    // 定义一个整数数组
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    // 获取数组长度
    int n = sizeof(arr) / sizeof(arr[0]);
    // 输出未排序数组
    printf("Unsorted array: \n");
    for(int i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
  
    // 调用选择排序函数对数组进行排序
    selectionSort(arr, n);

    // 输出排序后的数组
    printf("Sorted array: \n");
    for(int i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    return 0;
}

16.内存操作

#include <stdio.h>

int main()
{
    int a = 10;
    printf("memory is %p\n",&a);
    volatile unsigned int *p = (volatile unsigned int*)0x7fffffffd964;
    printf("memory is %p\n",p);
    return 0;
}

在 int main() 函数中:
    int a = 10;:定义了一个整数变量 a 并初始化为10。
    printf("memory is %p\n", &a);:使用%p格式说明符打印变量 a 的内存地址,即 &a将显示 a 变量在内存中的地址。
    volatile unsigned int *p = (volatile unsigned int*)0x7fffffffd964;:声明了一个 volatile 修饰的无符号整型指针变量 p,并将其指向内存地址 0x7fffffffd964。
    printf("memory is %p\n", p);:同样打印了指针 p 指向的内存地址。

volatile 关键字:
    在C语言中,volatile 是一个类型限定符,表示变量的值可能在程序的其他地方被修改,因此编译器不应该对这个变量的存取进行优化。
    在这段代码中,使用 volatile 关键字修饰指针 p,表明 p 指向的内存地址可能会发生变化。

注意事项:
    直接操作内存地址是一项高级操作,不应该随意进行。确保了解清楚内存地址的情况,避免访问非法内存区域。在实际开发中,应谨慎使用类似直接操作内存地址的技术,以确保程序的稳定性和安全性。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值