Linux C语言基础 day9

news/2024/9/14 1:58:15/ 标签: linux, c语言, 算法

目录

思维导图

学习目标:

学习内容:

1. 值传递与地址传递(非常重要)

1.1 值传递

1.2 地址传递

2. 递归函数

2.1 递归的概念

2.2 递归条件

2.3 递归思想

3. 指针

3.1 指针相关概念

3.2 指针变量的定义

3.2.1. 定义格式

3.2.2. 指针变量的初始化

3.3 指针变量的使用

课内练习:

课外作业:


思维导图


学习目标:

  • 一周掌握 C基础知识

学习内容:

1. 值传递与地址传递(非常重要)

1.1 值传递

说明:

        值传递过程中,形参与实参操作的是不同的内存空间

        当普通变量作为函数参数传递时,是单向的值传递,仅仅只是将实参的值,复制一份给形参使用,形参的改变不会影响到实参的值

例如:

#include<stdio.h>

//定义交换函数

void swap_1(int m, int n)

{

    //完成两个数的交换

    int temp = m;

    m = n;

    n = temp;

    printf("交换后,swap_1:: m = %d, n = %d\n", m, n);

}


 

/*********************主程序*********************/

int main(int argc, const char *argv[])

{

    //定义两个变量

    int num = 520;

    int key = 1314;

    //调用交换函数

    swap_1(num, key);

    printf("交换后,main:: num = %d, key = %d\n", num, key);


 

    return 0;

}

1.2 地址传递

说明:

        当实参传递的是数组名、指针或变量的地址(&num)时,可以理解成是地址传递

        地址传递过程中,形参与实参操作的是同一块内存空间

        形参对内存空间进行改变时,实参也跟着一起改变

例如:

#include<stdio.h>

//定义冒泡排序函数

void sort_up(int brr[], int n)

{

    printf("sizeof(brr) = %ld\n", sizeof(brr));   //

    //进行冒泡排序

    for(int i=1; i<n; i++)

    {

        for(int j=0; j<n-i; j++)

        {

            if(brr[j] > brr[j+1])

            {

                int temp = brr[j];

                brr[j] = brr[j+1];

                brr[j+1] = temp;

            }

        }

    }

    printf("排序结束\n");

}



 

/****************主程序********************/

int main(int argc, const char *argv[])

{

    //定义一个一位数组并初始化

    int arr[5] = {2,8,1,6,7};

    printf("sizeof(arr) = %ld\n", sizeof(arr));    //20

    //调用冒泡排序函数,完成升序排序

    sort_up(arr, 5);

    //输出排序后的结果

    printf("排序后:");

    for(int i=0; i<5; i++)

    {

        printf("%d\t", arr[i]);

    }

    printf("\n");

    return 0;

}

2. 递归函数

2.1 递归的概念

        所谓递归,就是一个函数直接或间接的形式调用自身,这样的函数调用,我们称为递归调用

2.2 递归条件

1. 递归出口:用于终止递归进行进行的条件

2. 递归表达式:能够让递归继续进行的函数调用

2.3 递归思想

        当直接解决规模比较大的问题不能进行时,需要先解决规模较小的原理一致的问题后,大的问题得以解决时,可以考虑使用递归

        逐层分解,逐层合并

例如:

#include<stdio.h>


 

int jiecheng(int n)

{

    if(n==0){

        return 1;

    }else

        return n*jiecheng(n-1);

}


 

/****************主程序********************/

int main(int argc, const char *argv[])

{

    int res = jiecheng(5);

    printf("%d",res);

    return 0;

}

3. 指针

3.1 指针相关概念

1. 引入目的:能够从地址的角度,找到内存中的数据,而不是以变量的角度去找,效率较高

2.  指针:就是内存地址编号

3.  指针变量:由于指针这个地址编号很难记忆,我们引入指针变量存储指针

存储地址的变量称为指针变量

4.  指针变量中,只能存储地址,作为一个特殊的数据类型,其大小是固定的 8 字节

3.2 指针变量的定义

3.2.1. 定义格式

        数据类型 * 指针名;

        例如:int * ptr;

3.2.2. 指针变量的初始化

        1、使用一个相同数据类型的变量的地址为其进行初始化

                int num = 520; int * ptr = &num //将num的地址赋值个指针变量 ptr //定义一个指针变量ptr,指向num

        2、使用一个已经初始化了的指针变量给一个新的指针变量进行初始化

                int * qtr = ptr; //此时表示两个指针变量同时存储了num的地址 int *qtr =&num

        3、使用地址的0 就是 NULL为其初始化

                int *wtr = NULL;

        4、注意:没有初始化的指针变量不能直接使用,因为该指针变量中存储了一个随机地址,如果对其进行更改,可能会导致系统瘫痪

        5、野指针:指向非法内存的指针称为野指针 产生情况:

                1)定义指针时,没有为其进行初始化

                2) 指向了一个内存空间,但是随着程序的进行,该内存空间被回收了,那么该指针也是野指针(悬空指针)

                3) 数组下标越界时,访问的地址也是野指针

3.3 指针变量的使用

        使用运算符 ‘ * ’来取得指针变量中的值,我们也称该运算为 取值运算

        &与*在指针的方面,互为逆运算

        int num = 520; int *ptr = &num;

                1) *&num ==> *(&num) ==> *(ptr) ==> num

                2) &*ptr ==> &(*ptr) ==> &(num) ==> ptr

                3) *&ptr ==>*(&ptr) ==> *(ptr的二级地址) ==> ptr

                4) &*num ==>报错


课内练习:

1.求n!结果

解析:

2.求斐波那契数列第n项的值

1 1 2 3 5 8 13 21 。。。

解析:


课外作业:

1.使用递归实现 求 n 的 k 次方

解析:

#include<stdio.h>

//函数

int jiecheng(int n,int k)

{

    if(k==0){

        return 1;

    }else

        return n*jiecheng(n,k-1); //返回n*n*......*n(k个n)

}


 

/****************主程序********************/

int main(int argc, const char *argv[])

{

    int k=0,n=0;

    printf("请输入底数n与指数k:");

    scanf("%d%d",&n,&k);

    int res = jiecheng(n,k);      //调用函数

    printf("值为:%d",res);

    return 0;

}

2.使用递归实现 strlen 的功能

解析:

#include<stdio.h>
int rec(char *str) {
    // 基本情况:如果字符串为空,则长度为0
    if (*str == '\0') {
        return 0;
    } else {
        // 递归步骤:当前字符加上剩余字符串的长度
        return 1 + rec(str + 1);
    }
}
int main(int argc, char const *argv[])
{
    char str[101]; // 假设输入的字符串长度不超过100
    printf("请输入一个字符串:");
    gets(str);              //获取字符串
    int len = rec(str);             //调用函数
    printf("字符串的长度是:%d\n", len);
    return 0;
}
 

3.使用递归实现汉诺塔问题

解析:

#include<stdio.h>
int  hanuo(int n) {
    if (n == 1) {
        return 1;
    } else {
        return hanuo(n-1)*2+1;
    }
}
int main(int argc, char const *argv[])
{
    int n=0;
    printf("请输入n的值:");
    scanf("%d",&n);
    int sum=hanuo(n);
    printf("次数为%d\n",sum);
    return 0;
}
 

4.定义一个函数将一个字符串从大到小排序

解析:

#include <stdio.h>
#include<string.h>
#define MAX 50
// 函数声明
int  change(char a[]);
int main() {
    char a[MAX];
    printf("请输入字符串:");
    scanf("%s",a);
    change(a);                          //调用函数
    printf("字符串从大到小排序为:%s\n",a);
    return 0;
}

int change(char a[]){
    int len=0;                          
    len= strlen(a);                 //定义数组长度
    int max=0;
    for (int i = 1; i < len; i++)             
    {
        for(int j=0;j <len-i;j++ ){
            if(a[j] < a[j+1]){                              //判断大小,进行交换三部曲
                 char temp = a[j+1];
                a[j+1] = a[j];
                a[j] = temp;
            }
        }
    }
}

5.实现一个函数,用于检查一个字符串是否是回文字符串(正序和反序都相同)

解析:

#include <stdio.h>
#include<string.h>
#define MAX 50
int huiwen(char s[]){
    int left=0;                                  //定义最左边下标
    int right = strlen(s)-1;          //定义最右边下标
    while (left <= right)
    {
       if(s[left] == s[right]){         //判断是否相等
           return 1;
           left++;                                  //逐渐向右递增
           right--;                                 //逐渐向左递增
       }else
       {
           return 0;
       }   
    }
}
int main() {
    char a[MAX];
    printf("请输入字符串:");
    scanf("%s",a);
    if(huiwen(a)==1){
        printf("是回文字符串\n");
    }else
    {
       printf("不是回文字符串\n");
    }
    return 0;
}

6.使用指针完成判断自己的主机存储多字节整数时,是大端存储还是小端存储

解析:

#include<stdio.h>
int main(int argc, char const *argv[])
{
    int a=0x12345678;
    char *p=(char *)&a;
    if(*p == 0x78){
        printf("为小端存储\n");
    }else if(*p ==0x12 ){
        printf("为大端存储\n");
    }
    return 0;
}

7.

解析:

#include<stdio.h>
#include<string.h>
#define MAX    50
int count(char a[MAX]){
    int sum=0;
    int inWord=0;
    gets(a);
        for (int i = 0; a[i] != '\0'; i++) {             
        if ((a[i] >= 'A' && a[i] <= 'Z') ||(a[i] >= 'a' && a[i] <= 'z')) {               // 检查当前字符是否为字母
            if (inWord==0) {                  // 如果之前不在单词中,现在是单词的开始
                sum++;                          // 增加单词计数
                inWord = 1; // 标记现在在单词中
            }
        } else {
            // 如果当前字符不是字母或数字,不在单词中
            inWord = 0;
        }
    }
    printf("单词数为%d个\n",sum);
}
int main(int argc, char const *argv[])
{
    char a[MAX];
    count(a);
    return 0;
}
 


http://www.ppmy.cn/news/1474673.html

相关文章

自动驾驶算法———车道检测(一)

“ 在本章中&#xff0c;我将指导您构建一个简单但有效的车道检测管道&#xff0c;并将其应用于Carla 模拟器中捕获的图像。管道将图像作为输入&#xff0c;并产生车道边界的数学模型作为输出。图像由行车记录仪&#xff08;固定在车辆挡风玻璃后面的摄像头&#xff09;捕获。…

Redis 中的跳跃表(Skiplist)基本介绍

Redis 中的跳跃表&#xff08;Skiplist&#xff09;是一种用于有序元素集合的快速查找数据结构。它通过一个多级索引来提高搜索效率&#xff0c;能够在对数时间复杂度内完成查找、插入和删除操作。跳跃表特别适用于实现有序集合&#xff08;sorted set&#xff09;的功能&#…

JavaScript中的Symbol类型是什么以及它的作用

聚沙成塔每天进步一点点 本文回顾 ⭐ 专栏简介JavaScript中的Symbol类型是什么以及它的作用1. 符号&#xff08;Symbol&#xff09;的创建2. 符号的特性3. 符号的作用3.1 属性名的唯一性3.2 防止属性被意外访问或修改3.3 使用内置的符号3.4 符号与属性遍历 4. 总结 ⭐ 写在最后…

vue3 + element-plus 表格行内编辑,如何实现表单校验?

问题描述&#xff1a; 当使用table实现行内编辑时&#xff0c;往往需要对必填项增加校验以及错误高度&#xff0c; 预期实现效果如下&#xff1a; 实现思路&#xff1a; 使用el-form表单自身的校验功能&#xff1a;通过el-from绑定对应表格行的prop&#xff0c; 实现校验 页面…

代码随想录-暑假算法第一天(数组篇)

代码随想录-暑假算法第一天(数组篇) 1. 二分查找 力扣题目链接(opens new window) 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否…

AIGC爬虫类代码示例:Scrapy和OpenAI API实现抓取内容并生成内容

对于我从事爬虫行业多年的经验来说&#xff0c;编程各种需求代码真是非常吃力且细致的活&#xff0c;随着AI的大火&#xff0c;我在设想有没有可能通过AI自动化程序实现自动抓取生成想要的文本内容。前提我是打算通过结合爬虫技术&#xff08;如Scrapy&#xff09;和生成式AI模…

【Django项目】基于Python+Django+MySQL的音乐网站系统项目

功能介绍 首页&#xff1a;歌曲分类、歌曲搜索、热门歌曲、热门下载、新歌推荐 歌曲排行&#xff1a;歌曲分类、分页功能 用户板块&#xff1a;用户登陆/注册、播放历史 歌曲详情&#xff1a;歌曲播放、当前播放列表、歌曲点评、歌曲播放插件、下载歌曲 系统后台&#xff1a;歌…

Spring——自动装配Bean

自动装配是Spring满足bean依赖的一种方式 Spring会在上下文中自动寻找&#xff0c;并自动给bean装配属性 在Spring中有三种装配的方式&#xff1a; 1. 在xml中显示配置 2. 在java中显示配置 3. 隐式的自动装配bean【重要】 测试 记得创建Cat、Dog、People类 public clas…

手撸俄罗斯方块(三)——游戏核心模块设计

手撸俄罗斯方块——游戏核心模块设计 开始游戏 按照之前的设计&#xff0c;我们需要游戏的必要元素之后即可开始游戏&#xff0c;下面以控制台上运行俄罗斯方块为例进行展开讲解。 import { ConsoleCanvas, ConsoleController, ConsoleColorTheme, Color } from shushanfx/t…

18.按键消抖模块设计(使用状态机,独热码编码)

&#xff08;1&#xff09;设计意义&#xff1a;按键消抖主要针对的时机械弹性开关&#xff0c;当机械触点断开、闭合时&#xff0c;由于机械触点的弹性作用&#xff0c;一个按键开关在闭合时不会马上稳定地接通&#xff0c;在断开时也不会一下子就断开。因而在闭合以及断开的瞬…

Linux rpm和ssh损坏修复

背景介绍 我遇到的问题可能和你的不一样。但是如果遇到错误一样也可以按此方案尝试修复。 我是想在Linux上安装Oracle&#xff0c;因为必须在离线环境下安装。就在网上搜一篇文章linux离线安装oracle&#xff0c;然后安装教程走&#xff0c;进行到安装oracle依赖包的时候执行了…

React:useState和useEffect

最近因为想要开发一个简单的应用才开始接触React。但是并没有系统学习React&#xff0c;所以这篇博客可能会写的不够专业。 1. Hooks 在程序设计语言中&#xff0c;钩子(hook)是一种机制&#xff0c;它可以允许程序在某些预定的事件或位置执行特定的代码。在React中&#xff0c…

Web 性能入门指南-1.2 分析在线零售 Web 性能及优化方向

让顾客满意是零售业成功的秘诀。事实证明&#xff0c;提供快速、一致的在线体验可以显著提高零售商关心的每项指标——从转化率和收入到留存率和品牌认知度。 本文大纲&#xff1a; 页面速度影响在线零售业务数据 如何将您的网站速度与竞争对手进行比较 性能优化入门&#xf…

超级好用的java http请求工具

kong-http 基于okhttp封装的轻量级http客户端 使用方式 Maven <dependency><groupId>io.github.kongweiguang</groupId><artifactId>kong-http</artifactId><version>0.1</version> </dependency>Gradle implementation …

独特功能的视频号矩阵系统源码,支持多短视频平台自动发布和定时发布

在短视频行业竞争日趋激烈的今天&#xff0c;一个高效的视频发布系统对于内容创作者和营销团队来说至关重要。视频号矩阵系统源码以其独特的功能&#xff0c;为多平台自动发布和定时发布提供了强大的技术支持。 多平台自动化发布&#xff1a;无缝内容分发 视频号矩阵系统源码…

掌握MOJO命令行:参数解析的艺术

在软件开发中&#xff0c;命令行接口&#xff08;CLI&#xff09;是一种与程序交互的强大方式&#xff0c;它允许用户通过终端输入指令和参数来控制程序的行为。对于MOJO语言&#xff0c;即使它是一个假想的编程语言&#xff0c;我们也可以设想它具备解析命令行参数的能力。本文…

Oracle执行一条SQL的内部过程

一、SQL语句根据其功能主要可以分为以下几大类&#xff1a; 1. 数据查询语言&#xff08;DQL, Data Query Language&#xff09; 功能&#xff1a;用于从数据库中检索数据&#xff0c;常用于查询表中的记录。基本结构&#xff1a;主要由SELECT子句、FROM子句、WHERE子句等组成…

使用Docker、Docker-compose部署单机版达梦数据库(DM8)

安装前准备 Linux Centos7安装&#xff1a;https://blog.csdn.net/andyLyysh/article/details/127248551?spm1001.2014.3001.5502 Docker、Docker-compose安装&#xff1a;https://blog.csdn.net/andyLyysh/article/details/126738190?spm1001.2014.3001.5502 下载DM8镜像 …

Bilibili Android一二面凉经(2024)

BiliBili Android一二面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《BiliBili Android一二面凉经(2024)》。 面试职位: 高级Android开发工程师&…

Openresty+lua 定时函数 ngx.timer.every

ngx.timer.every 是 OpenResty 中的一个函数&#xff0c;用于创建定时器&#xff0c;以便定期执行某个函数或代码块。它的用法如下&#xff1a; local delay 5 -- 定时器间隔时间&#xff0c;单位为秒ngx.timer.every(delay, function(premature)-- 这里是定时执行的代码块i…