C#学习 - 方法的定义、调用、调试

news2024/12/22 19:59:17

方法

  • 方法(Method)是由C/C++中的函数(Function)发展而来的
//C语言
#include <stdio.h>
int Add(int x, int y)
{
	return x + y;
}//函数
int main(void)
{
	int a = 4;
	int b = 2;
	int c = Add(a, b);
	printf("%d + %d = %d\n", a, b, c);
	return 0;
}
//C++
#include <iostream>
int Add(int x, int y)
{
	return x + y;
}//函数
int main()
{
	int a = 4;
	int b = 2;
	int c = Add(a, b);
	std::cout << a << " + " << b << " = " << c;
	return 0;
}

方法是面向对象,当一个函数以类的成员出现的时候就叫方法,所以方法又叫成员函数
在编写C++程序时,选择添加类(Class),然后输入类名,后面的 .h 文件就是类的声明,而 .cpp 文件就是类的定义(在C#中类的声明和定义是放在一起的)C++程序添加类

//ABC.h - 类的声明
#pragma once
class ABC
{
public:
	void ShowHello();
};

//ABC.cpp - 类的定义
#include "ABC.h"
#include <iostream>
void ABC::ShowHello()
{
	std::cout << "Hello World";
}

//use.cpp
#include <iostream>
#include "ABC.h"
int main()
{
	ABC* pABC = new ABC();
	//此处已经有了C#方法的雏形了
	pABC->ShowHello();
	return 0;
}
  • 方法是类(或结构体)的成员

C#中函数不能独立于类(或结构体)之外
只有作为类(或结构体)的成员出现时,函数才能被称为方法

namespace ConsoleApp1
{
    int Add(int x, int y)
    {
        return x + y;
    }
    internal class Program
    {
        static void Main(string[] args)
        { }
    }
}

上段代码中的函数没有在类中,编译会报错

  • 方法是类(或结构体)最基本的成员之一
    类(或结构体)有两个最基本的成员 - 字段和方法(成员变量和成员函数)
    方法表示类(或结构体)所能干的事情
  • 使用方法和函数的目的
    1. 隐藏复杂的逻辑;
    2. 把大算法分解为小算法;
    3. 复用;
//未复用
class Tool
{
	public double GetCicleArea(double R)
	{
		return 3.14 * R * R;
	}
    public double GetCylinderVolume(double R, double H)
    {
        return 3.14 * R * R * H;
    }
    public double GetConeVolume(double R, double H)
    {
        return 3.14 * R * R * H / 3;
    }
}
//复用
class Tool
{
	public double GetCicleArea(double R)
	{
		return 3.14 * R * R;
	}
    public double GetCylinderVolume(double R, double H)
    {
        return GetCicleArea(R) * H;
    }
    public double GetConeVolume(double R, double H)
    {
        return GetCyliderVolume(R, H) / 3;
    }
}

将一个大的算法分解为小的算法,再由算法一个一个解决,就是自顶向下逐步求精的方法

方法的声明与调用

方法的声明

函数头 + 函数体
函数头:特性 + 有效的方法的修饰符 + partial + 返回类型 + 方法名 + 类型参数列表 + ( + 形式参数列表 + )+ 类型参数约束句子
其中只有 返回类型 & 方法名 & **()**是必须要的;其中 类型参数约束句子 只有在有 类型参数列表 出现时才能出现
方法名最好使用动词或动词短语,所有单词首字母大写(Pascal命名法)
形式参数(parameter,简称:形参):是一种变量,会参与构成方法的算法逻辑

静态方法和实例方法

静态方法与类绑定,非静态方法(实例方法)与实例绑定

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Tool t = new Tool();
            Console.WriteLine(t.Add(1, 2));
            //实例方法与实例绑定
            Console.WriteLine(Tool.Sub(1,2));
            //静态方法与类绑定
        }
    }
    class Tool
    {
        public int Add(int x, int y)
        { 	//实例方法
            return x + y;
        }
        public static int Sub(int x, int y)
        {	//静态方法
            return x - y;
        }
    }
}

调用方法

方法调用:方法名 + ( + 实际参数列表 + )
实际参数(Argument,简称:实参):实际参数列表需要与定义方法时的形式参数列表相匹配
以上面那段代码为例:

int x = Tool.Sub(1);
//此时实际参数个数与形式参数不匹配
int y = Tool.Sub(1.0, 2.5);
//此时实际参数类型与形式参数不匹配

构造器

构造器(Constructor)是类型的成员之一,构造器就是构造函数
狭义的构造器就是实例构造器(Instance constructor)

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Human human = new Human();
            //上行代码中的 () 就是调用构造器
            Console.WriteLine(human.ID);
            Console.WriteLine(human.Name);

            People people = new People();
            Console.WriteLine(people.ID);
            Console.WriteLine(people.Name);

            Student student = new Student(1, "None");
            //构造器带参数时调用也需要带参数
            Console.WriteLine(student.ID);
            Console.WriteLine(student.Name);
        }
    }
    class Human
    { //当声明一个类后,没有准备构造器时,编译器会自动为其准备一个默认构造器
        //默认构造器可以把内存中的对象的字段进行初始化,就是将 ID 和 Name 进行初始化
        public int ID;
        public string Name;
    }
    class People
    {
        public People()
        {   //创建构造器时,构造函数名要与类一致
            this.ID = 0;
            this.Name = "NULL";
        }
        public int ID;
        public string Name;
    }
    class Student
    {
        public Student(int id, string name)
        {
            this.ID = id;
            this.Name = name;
        }
        public int ID;
        public string Name;
    }
}

一个类中可以有多个构造器

class People
{
    public People(int id, string name)
    {
        this.ID = id;
        this.Name = name;
    }
    public People()
    {
        this.ID = 0;
        this.Name = "NULL";
    }
    public int ID;
    public string Name;
}

构造器的内存原理

默认构造器

Human human = new Human();
class Human
{
	public int ID;
	public string Name;
}

第一个代码创建了一个human变量,human变量存储在栈区中(栈区存储由高字节位到低字节位)
new操作符开始执行时,在堆区找足够的内存空间作为实例的内存,而 int 需要占4字节,string 需要占4字节,所以最后占用了8个字节。构造时就对这8个字节进行切割,前4个为int类型,后4个为string类型,然后默认构造器将这8个字节中的值全赋值为0
最后将实例的地址存储在human变量中

带参数的构造器

Human human = new Human(1, "One");
class Human
{
	public Human(int id, string name)
	{
		this.ID = id;
		this.Name = name;
	}
	public int ID;
	public string Name;
}

依旧是在栈区分配human变量的内存空间,然后在堆区分配8字节,然后开始切割这8个字节,再在前4个字节中存入1,在后4个字节中存入“One”
最后把实例的地址放进human变量的内存空间中

方法的重载(Overload)

当一个类中的两个方法的名称一致时,方法签名不能一致
方法签名(Method signature)由方法名称、类型形参的个数和方法的形参(由左到右的顺序)的类型、种类(值、引用、输出)组成,方法签名不包含返回类型

class Tool
{
    public int Add(int a, int b)
    { return a + b; }
    public double Add(double a, double b)
    { return a + b; }
    public int Add(int a, int b, int c)
    { return a + b + c; }
    public int Add(ref int a, out int b)
    { b = 10; return a + b; }
    //ref就是引用、out就是输出
}

构造器也可以有重载,构造器的签名由每一个形参(从左到右的顺序)的类型和种类(值、引用、输出)组成
重载决策:根据调用方法时实参的类型来决定调用哪一个方法。如:

Console.WriteLine(100);
Console.WriteLine("Hello World");

对方法进行debug

debug可以找到bug发生的地方,也可以了解到程序运行的原理

设置断点(breakpoint)

设置断点后,运行程序时会自动停在断点设置处断点
红色就是断点标识,设置快捷键是F9,然后按F5进行调试,就会执行时停到断点处调试后
当红点标识变成上图标识时,就是程序执行停在了那里

观察方法调用时的调用堆栈(call stack)

Call stack
上图中第一行就是断点处的方法(函数)
第二行就是调用它的函数,可以双击跳到所需位置
实际代码中此处可能会层层叠加,最后一行就是最外层调用,而红点标识处就是断点处

逐语句(Step-into)、逐过程(Step-over)、跳出(Step-out)

Step-into(F11)会进入所调用的方法中去
Step-over(F10)不会进入所调用的方法中,没有Step-into细致
Step-out(Shift+F11)可以从一个方法中直接回到调用它的那段代码上

观察局部变量的值与变化

在监视中观察监视
将鼠标移到变量处,可以标识出变量的值,当语句调试到那一处时,会自动将被标识的变量的值显示出来

方法调用时栈内存的分配

stack frame:一个方法被调用时,它在栈内存当中的布局
当代码执行到一个方法时,在栈区中分配一个内存
当在A方法中调用一个B方法时用到了实际参数,传的参数也会分配到栈区中,在C#中这些实际参数归A方法管
分配参数内存时,在C#中先分配左边的参数,再分配右边的参数
当一个方法调用结束后,会回收给它分配的内存,且传递的实参所占的内存也会被回收
方法的返回值会存在cpu的寄存器(一种高速内存)中,当寄存器空间不够存放返回值时才会存放在栈区

using System;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Tool tool = new Tool();
            Console.WriteLine(tool.Add(1, 2));
        }
    }
    class Tool
    {
        public int Add(int a, int b)
        {
            int c = Sub(a, b);
            return c;
        }
        public int Sub(int a, int b)
        {
        	int c = a - b;
            return c;
        }
    }
}

栈区内存分配
上图就是上段代码执行到方法Sub时的栈区内存分配,继续执行就会从上往下慢慢回收已经调用结束的方法所占的内存
注:上图只标识了参数内存分配,实际上还有其他很多元素会分配到栈区中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql 删除索引 索引长度还在,数据内存 索引内存没有减少

在我们针对数据表进行了大量删除或者删除掉某个无用的索引之后&#xff0c;该表占的数据内存或者索引并没有明显的变换&#xff0c;这是因为删除操作后在数据文件中留下碎片所致。 查看数据与索引 SELECTTABLE_NAME,concat( TRUNCATE ( data_length / 1024 / 1024, 2 ), MB …

腾讯云4核8G服务器CVM S5性能测评(CPU/流量/系统盘)

腾讯云4核8G服务器CVM标准型S5实例性能测评&#xff0c;包括CPU型号、内存、系统盘、CVM实例规格性能测评&#xff0c;腾讯云4核8G租用优惠价格表&#xff0c;腾讯云服务器网分享腾讯云4核8G服务器CVM S5性能测评和租用费用&#xff1a; 目录 腾讯云4核8G服务器CVM S5性能测评…

【C++】简单理解:将整数(浮点数)转换为字符串(string),将字符串(string)转换为整数(浮点数)方法

用stringstream类&#xff0c;口诀&#xff1a;过滤一下就转化 头文件#include<sstream> 例子&#xff1a;将整数12和浮点数12.34转化为字符串 int main() {int x 12;double d 12.34;string s;//创建一下对象strstringstream str;//过滤一下就转化str << x;st…

分享芯片行业有趣的小知识

随着拜登签署《芯片与科学家法案》&#xff0c;全球芯片争夺战进一步升温&#xff0c;我国芯片市场再次面临霸权主义的挑战。尽管困难重重&#xff0c;我们决不会停止在芯片领域的探索与发展&#xff0c;这彰显了芯片对国家的至关重要性。除了其重要性&#xff0c;芯片还有许多…

矿山边坡安全监测及预警系统解决方案

1.建设背景 近年来&#xff0c;矿山安全问题一直受到国家和社会的高度关注。为了全面提升矿山安全生产水平&#xff0c;国家矿山安全监察局和各省级非煤矿山安全监管部门开展了一项重大举措&#xff1a;推广并实施露天矿山边坡监测系统。 矿山边坡和排土场安全是露天矿山安全生…

vs2019配置sfml外部库出现的问题

问题描述 在debug模式下程序正常运行&#xff0c;在release模式中报错 解决 C/C Windows环境下 boost 安装使用教程 Debug 通常称为调试版本&#xff0c;它包含调试信息&#xff0c;并且不作任何优化&#xff0c;便于程序员调试程序。 Release&#xff1a;Release通常称为发…

【HCIE】03.BGP高级特性

每一条BGP路由都可以携带多个路径属性&#xff0c;针对其属性也有特有的路由匹配工具&#xff0c;包括&#xff1a;AS Path Filter和Community Filter。 import方向的属性&#xff0c;出现在如策略里面&#xff0c;加入到BGP路由表中&#xff0c;再传给路由表里&#xff0c;出去…

产品波士顿矩阵

随着公司产品的增多&#xff0c;每个产品的生命周期节点各不相同&#xff0c;很多时候我们往往在产品结构、资源分配方面会产生各种问题&#xff0c;导致需要发展的产品得不到资源&#xff0c;消耗资源的产品却有无法增长&#xff0c;所谓不聚焦导致的问题其实是资源和发展错配…

RP9学习-1

一.基础 1.10个面板位置示意图&#xff1a; 2.常用英文 1.鼠标点击&#xff1a;click or tap 3.工作区 1.恢复默认工作区&#xff1a; view-->reset view 2.自定义工作区&#xff1a; 可以用鼠标左键拖动面板到独立的位置或者吸附到其他面板上 3.自定义工具栏 view-->T…

4核8G服务器腾讯云CVM S5性能如何?CPU型号及租用价格

腾讯云4核8G服务器CVM标准型S5实例性能测评&#xff0c;包括CPU型号、内存、系统盘、CVM实例规格性能测评&#xff0c;腾讯云4核8G租用优惠价格表&#xff0c;腾讯云服务器网分享腾讯云4核8G服务器CVM S5性能测评和租用费用&#xff1a; 目录 腾讯云4核8G服务器CVM S5性能测评…

让AI帮你做出回答-钉钉问答机器人来啦

什么是问答机器人 问答机器人是一种人工智能系统&#xff0c;它可以根据用户提出的问题&#xff0c;自动地搜索并提供相关的答案。这些机器人通常基于自然语言处理技术&#xff0c;可以理解用户提出的问题&#xff0c;并能够快速地给出答案。 问答机器人通常会在多个数据源中…

怎么给商品图片去除背景,制作商品白底图?

很多商家在上架新产品时平台都会要求上传一张白底图&#xff0c;上传商品白底图不仅可以更快速的通过资源位审核&#xff0c;还更容易获得平台的免费曝光机会&#xff01; 我们在编辑商品主图、上传商品素材图片的时候&#xff0c;经常需要用到白底图。但是很多朋友都不知道怎…

虹科分享 | 解决外科医生的担忧:AR让技术自己开口说话

在手术室中&#xff0c;分心可能导致严重错误和伤害&#xff0c;这凸显了在手术过程中减少对外科医生干扰的重要性。对于外科医生来说&#xff0c;在长时间的手术过程中&#xff0c;引入新技术设备时需要考虑多种因素。根据Vuzix对500多名外科医生的综合调查显示&#xff0c;使…

华为云云耀云服务器L实例使用教学:快速安装mysql

最近趁着华为云828大促活动&#xff0c;薅了一台云耀云服务器L实例&#xff0c;由于我买的是纯净版linux系统&#xff0c;所以上面啥也没有&#xff0c;我有一些自己的Java应用&#xff0c;后面就准备全部迁移到这台机器 jdk已经装好了&#xff0c;接下来准备把mysql搞定 首先…

JSR 303 校验

前言&#xff1a; JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架&#xff0c;它已经包含在 JavaEE 6.0 标准中。JSR 303 通过在 Bean 属性上标注类似于 NotNull、Max 等 JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架&#xff0c;它已经包含在 JavaEE 6.0 标…

操作系统学习笔记---计算机系统概述

目录 概念 功能和目标 特征 并发 共享&#xff08;资源共享&#xff09; 虚拟 异步 发展与分类 手工操作阶段&#xff08;无OS&#xff09; 批处理阶段 单道批处理系统 多道批处理系统 分时操作系统 实时操作系统 网络操作系统 分布式计算机系统 个人计算机操…

EmguCV-C#版本Opencv图像识别和处理

目录 0、简介 1、图像处理 &#xff08;1&#xff09;颜色处理 &#xff08;2&#xff09;图像差 &#xff08;3&#xff09;图像拼接 &#xff08;4&#xff09;直方图 &#xff08;5&#xff09;颜色空间/通道提取 2、预处理 &#xff08;1&#xff09;均衡化 &…

无涯教程-JavaScript - MIRR函数

描述 MIRR函数针对一系列定期现金Stream返回修改后的内部收益率。 MIRR会同时考虑投资成本和现金再投资收到的利息。 语法 MIRR (values, finance_rate, reinvest_rate)争论 Argument描述Required/OptionalValues 包含数字的单元格的数组或引用。这些数字表示定期发生的一系…

MATLAB入门-字符串操作

MATLAB入门-字符串操作 注&#xff1a;本篇文章是学习笔记&#xff0c;课程链接是&#xff1a;link MATLAB中的字符串特性&#xff1a; 无论是字符还是字符串&#xff0c;都要使用单引号来‘’表示&#xff1b;在MATLAB中&#xff0c;字符都是在矩阵中存储的&#xff0c;无论…