黑马程序员_c#基础知识学习笔记:习题ReadInt及冒泡排序

本博客展示了如何在C#中通过方法读取用户输入的整数,并实现冒泡排序算法对输入的整数数组进行排序。包括错误处理确保用户输入有效,以及排序过程的详细解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

1.读取输入的整数,定义成方法,多次调用(如果用户输入的数字,则返回,否则提示用户重新输入)

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCAPP
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("请输入你的年龄?");
            int iAge = ReadInt();
            Console.WriteLine("你刚刚输入的年龄为"+iAge);

            Console.WriteLine("请输入你是哪一年出生的?");
            int iYear = ReadInt();
            Console.WriteLine("噢,你是{0}年出生的呀!",iYear);

            Console.WriteLine("请输入你们班有多少人?");
            int iCount = ReadInt();
            Console.WriteLine("你们班共有{0}人",iCount);

            Console.ReadKey();
        }
        public static int ReadInt()
        {
            int iNumber = 0;
            do
            {
                try
                {
                    iNumber = Convert.ToInt32(Console.ReadLine());
                    return iNumber;
                }
                catch
                {
                    Console.WriteLine("输入有误,请重新输入!");
                }
            }while(true);
           
        }
    }


}

运行效果为:

2.冒泡排序:

思路:让数组中的元素两两比较(第 i 个与第  i + 1 个比较),经过 n(i-1)遍两两比较,数组中的元素能按照我们预期的规律排序.

要从大到小排序,我们进行两两比较的时候用 <  符号

10 20 30 40 50 60 70      原始数据  7 个元素

20 30 40 50 60 70 10      第1趟 比较了 6 次

30 40 50 60 70 20 10      第2趟 比较了 5 次

40 50 60 70 30 20 10      第3趟 比较了 4 次

50 60 70 40 30 20 10      第4趟 比较了  3 次

60 70 50 40 30 20 10       第5趟 比较了 2 次

70 60 50 40 30 20 10       第6趟 比较了 1 次

也就是 n 个数需要排 n - 1 趟

第 t  趟比较的次数为: n -  t 次

循环变量 i = 0 第一趟

                  i = 1 第二趟

由此可知趟数: i + 1;  即 t = i + 1;

for(int j = 0;j<n-t;j++) 因为 t = i+1 所以此循环条件可以改成 j < n - i - 1;

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyCAPP
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] scores = { 18,20,48,76,20,38,87,90,37,45,65,65,34,97};

            for (int i = 0; i < scores.Length - 1; i++)  //控制比较的趟数
            {
                for (int j = 0; j < scores.Length -i- 1; j++)
                {
                    if(scores[j] < scores[j+1])
                    {
                        int temp = scores[j];
                        scores[j] = scores[j+1];
                        scores[j + 1] = temp;
                    }
                }
            }

            for (int i = 0; i < scores.Length; i++)
            {
                Console.Write(scores[i]+ " ");
            }

            Console.ReadKey();

        }
      
    }

}

运行代码及效果为:

 

 

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.youkuaiyun.com/heima/

<think>好的,我现在需要处理用户关于Android HIDL框架中的一个特定方法的问题。用户询问的是`android::hardware::graphics::composer::V2_2::BpHwComposerClient::_hidl_executeCommands_2_2`方法,并提供了一个详细的构建ID和调用栈信息。用户可能遇到了崩溃或性能问题,特别是在这个方法的某个偏移地址(+488)处。 首先,我要回顾之前的回答,确保这次回答保持一致但更深入。之前已经解释了该方法的作用、代码结构、调用链路和调试技巧,但现在用户提供的额外信息(如BuildId和.cfi+488)需要进一步分析。 接下来,我需要理解用户提供的具体参数。方法签名中的参数包括`HidlInstrumentor*`和`unsigned int`,这些可能涉及HIDL的调试或性能分析工具。用户可能是在分析崩溃日志或反汇编后的代码,需要定位问题所在。 用户提到的BuildId(ef6c132a4ce65fcdd8cde1f2b3a2e1a6)可能用于符号化堆栈跟踪,以确定具体的代码位置。我需要解释如何利用BuildId和偏移地址来定位代码,比如使用addr2line工具或NDK中的调试工具。 另外,调用栈中的.cfi+488表明这是调用帧信息中的偏移,可能涉及栈展开或异常处理。我需要考虑常见的崩溃原因,如空指针、内存损坏、参数错误等,并提供相应的调试建议。 用户可能希望知道如何分析这个特定的崩溃点,因此需要分步骤说明如何解析符号、检查参数传递、验证HAL实现版本兼容性等。同时,要提醒用户检查HIDL接口版本是否匹配,以及是否正确处理异步回调。 最后,要确保回答结构清晰,分点列出可能的问题和解决方法,并提供实用的命令示例,如使用addr2line、logcat过滤、strace跟踪等。同时,保持语言简洁,避免过于技术化的术语,让用户能够逐步排查问题。</think>--- ### 1. **问题定位:符号与调用栈解析** 你提供的符号信息包含构建ID和代码偏移量(`.cfi+488`),通常出现在崩溃日志或反汇编代码中。这表明你需要分析该方法的**具体执行流程**或**崩溃点**。以下是关键解析步骤: #### 符号信息分解 - **完整符号**: ```cpp android::hardware::graphics::composer::V2_2::BpHwComposerClient::_hidl_executeCommands_2_2( android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, std::function<void(...)>) ``` - **BuildId**: `ef6c132a4ce65fcdd8cde1f2b3a2e1a6` 用于唯一标识该二进制文件(如`libhidlbase.so`或厂商HAL库),可通过`ndk-stack`或`addr2line`工具定位源码位置。 - **偏移量`+488`**: 表示崩溃点在该方法汇编代码的偏移地址(可能对应某条指令或参数传递逻辑)。 --- ### 2. **方法参数详解** ```cpp _hidl_executeCommands_2_2( android::hardware::IInterface* _hidl_this, // Binder代理对象指针 android::hardware::details::HidlInstrumentor* _hidl_instrumentor, // 调试/性能分析工具接口 unsigned int _hidl_flags, // 事务标志(同步/异步) const android::hardware::hidl_vec<android::hardware::hidl_handle>& commands, // 命令集合 std::function<void(Error, bool, uint32_t, const hidl_vec<handle>&)> _hidl_cb // 异步回调 ) ``` - **关键参数**: - `HidlInstrumentor*`: 用于HIDL接口的调试和性能追踪(如记录事务耗时)。 - `_hidl_flags`: 标志位(如`TF_ONE_WAY`表示异步调用)。 - `_hidl_cb`: 回调函数传递执行结果(错误码、输出数据等)。 --- ### 3. **崩溃场景与常见原因** #### 典型崩溃点(`.cfi+488`) 在`+488`偏移处崩溃可能由以下原因导致: 1. **空指针解引用**:`_hidl_this`或`_hidl_instrumentor`指针无效。 2. **Binder事务失败**:HAL服务未响应或Binder驱动异常。 3. **命令数据错误**:`commands`包含无效句柄或未映射的共享内存。 4. **回调函数异常**:`_hidl_cb`被提前释放或未正确初始化。 #### 调试步骤 1. **符号化崩溃地址**: ```bash # 使用NDK工具链解析地址 addr2line -e <二进制文件路径> -f -C -i <崩溃地址> # 示例(需替换BuildId和偏移量): addr2line -e /system/lib64/vendor.example.graphics@2.2.so \ -a 0x12345678 # 基地址 + 偏移量 ``` 2. **检查HIDL日志**: ```bash adb logcat | grep -E "HIDL|ComposerClient|BpHwComposerClient" ``` 3. **验证HAL服务状态**: ```bash adb shell lshal list | grep graphics.composer # 确保服务状态为`alive`且版本匹配(如`2.2::IComposerClient/default`) ``` --- ### 4. **代码执行流程与关键逻辑** #### 事务发送流程(伪代码) ```cpp Return<void> BpHwComposerClient::_hidl_executeCommands_2_2(...) { // 1. 序列化参数到Parcel Parcel data, reply; data.writeInterfaceToken(IComposerClient::descriptor); data.writeUint64(display); data.writeBuffer(commands.data(), commands.size()); // 2. 发起Binder事务 status_t status = remote()->transact(TRANSACTION_EXECUTE_COMMANDS_2_2, data, &reply, _hidl_flags); // 3. 反序列化结果并触发回调 if (status == OK) { Error error = static_cast<Error>(reply.readInt32()); hidl_vec<handle> outData; reply.readBuffer(&outData); _hidl_cb(error, outData); // 可能崩溃点(回调函数无效) } return Void(); } ``` - **潜在崩溃点**: - `remote()->transact()`:Binder通信失败。 - `reply.readBuffer()`:反序列化数据格式错误。 - `_hidl_cb(...)`:回调函数已被销毁。 --- ### 5. **实战调试建议** #### 场景1:空指针崩溃 - **排查点**: - 检查`_hidl_this`是否来自有效的`BpHwComposerClient`实例。 - 确认`_hidl_instrumentor`是否在HIDL调试模式下初始化。 #### 场景2:Binder事务失败 - **排查点**: - 使用`binderdebug`启用Binder调试: ```bash adb shell "echo binder_debug > /sys/module/binder/parameters/debug_mask" ``` - 检查HAL服务崩溃日志: ```bash adb logcat | grep -A 10 "FATAL EXCEPTION" ``` #### 场景3:命令数据异常 - **排查点**: - 验证`commands`中的`hidl_handle`是否通过`native_handle_create`正确创建。 - 使用`dumpsys SurfaceFlinger`确认图形命令提交是否超时。 --- ### 6. **扩展:HIDL与Binder交互机制** - **Binder事务类型**: $$ \text{HIDL方法调用} \rightarrow \text{Binder事务码(如}\text{TRANSACTION_EXECUTE_COMMANDS_2_2}\text{)} $$ - 事务码在自动生成的`IComposerClient.h`中定义(如`TRANSACTION_executeCommands_2_2 = 42`)。 - **数据序列化**: 参数通过`Parcel`对象序列化为二进制流,HAL服务通过`Bn端`的`onTransact()`反序列化并执行。 --- ### 7. **总结** - **核心问题**:崩溃可能由参数错误、Binder通信失败或回调异常导致。 - **调试优先级**: 1. 符号化崩溃地址定位代码位置。 2. 检查HIDL日志确认事务状态。 3. 验证HAL服务版本与接口兼容性。 如需进一步分析,请提供完整的崩溃日志或调用栈片段!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值