-
实例字符串运算符实例如下:实例#!/bin/bash# author:华为教程# url:www.huawei.coma="abc"b="efg"if [ $a = $b ]then echo "$a = $b : a 等于 b"else echo "$a = $b: a 不等于 b"fiif [ $a != $b ]then echo "$a != $b : a 不等于 b"else echo "$a != $b: a 等于 b"fiif [ -z $a ]then echo "-z $a : 字符串长度为 0"else echo "-z $a : 字符串长度不为 0"fiif [ -n "$a" ]then echo "-n $a : 字符串长度不为 0"else echo "-n $a : 字符串长度为 0"fiif [ $a ]then echo "$a : 字符串不为空"else echo "$a : 字符串为空"fi执行脚本,输出结果如下所示:abc = efg: a 不等于 babc != efg : a 不等于 b-z abc : 字符串长度不为 0-n abc : 字符串长度不为 0abc : 字符串不为空文件测试运算符文件测试运算符用于检测 Unix 文件的各种属性。属性检测描述如下:其他检查符:-S: 判断某文件是否 socket。-L: 检测文件是否存在并且是一个符号链接。实例变量 file 表示文件 /var/www/huawei/test.sh,它的大小为 100 字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:实例#!/bin/bash# author:华为教程# url:www.huawei.comfile="/var/www/huawei/test.sh"if [ -r $file ]then echo "文件可读"else echo "文件不可读"fiif [ -w $file ]then echo "文件可写"else echo "文件不可写"fiif [ -x $file ]then echo "文件可执行"else echo "文件不可执行"fiif [ -f $file ]then echo "文件为普通文件"else echo "文件为特殊文件"fiif [ -d $file ]then echo "文件是个目录"else echo "文件不是个目录"fiif [ -s $file ]then echo "文件不为空"else echo "文件为空"fiif [ -e $file ]then echo "文件存在"else echo "文件不存在"fi执行脚本,输出结果如下所示:文件可读文件可写文件可执行文件为普通文件文件不是个目录文件不为空文件存在
-
实例布尔运算符实例如下:实例#!/bin/bash# author:华为教程# url:www.huawei.coma=10b=20if [ $a != $b ]then echo "$a != $b : a 不等于 b"else echo "$a == $b: a 等于 b"fiif [ $a -lt 100 -a $b -gt 15 ]then echo "$a 小于 100 且 $b 大于 15 : 返回 true"else echo "$a 小于 100 且 $b 大于 15 : 返回 false"fiif [ $a -lt 100 -o $b -gt 100 ]then echo "$a 小于 100 或 $b 大于 100 : 返回 true"else echo "$a 小于 100 或 $b 大于 100 : 返回 false"fiif [ $a -lt 5 -o $b -gt 100 ]then echo "$a 小于 5 或 $b 大于 100 : 返回 true"else echo "$a 小于 5 或 $b 大于 100 : 返回 false"fi执行脚本,输出结果如下所示:10 != 20 : a 不等于 b10 小于 100 且 20 大于 15 : 返回 true10 小于 100 或 20 大于 100 : 返回 true10 小于 5 或 20 大于 100 : 返回 false逻辑运算符以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:实例逻辑运算符实例如下:实例#!/bin/bash# author:华为教程# url:www.huawei.coma=10b=20if [[ $a -lt 100 && $b -gt 100 ]]then echo "返回 true"else echo "返回 false"fiif [[ $a -lt 100 || $b -gt 100 ]]then echo "返回 true"else echo "返回 false"fi执行脚本,输出结果如下所示:返回 false返回 true字符串运算符下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
-
Shell 和其他编程语言一样,支持多种运算符,包括:算数运算符关系运算符布尔运算符字符串运算符文件测试运算符原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):实例#!/bin/bashval=`expr 2 + 2`echo "两数之和为 : $val"运行实例 »执行脚本,输出结果如下所示:两数之和为 : 4两点注意:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。实例算术运算符实例如下:实例#!/bin/bash# author:华为教程# url:www.hauwei.coma=10b=20val=`expr $a + $b`echo "a + b : $val"val=`expr $a - $b`echo "a - b : $val"val=`expr $a \* $b`echo "a * b : $val"val=`expr $b / $a`echo "b / a : $val"val=`expr $b % $a`echo "b % a : $val"if [ $a == $b ]then echo "a 等于 b"fiif [ $a != $b ]then echo "a 不等于 b"fi执行脚本,输出结果如下所示:a + b : 30a - b : -10a * b : 200b / a : 2b % a : 0a 不等于 b注意:乘号(*)前边必须加反斜杠(\)才能实现乘法运算;if...then...fi 是条件语句,后续将会讲解。在 MAC 中 shell 的 expr 语法是:$((表达式)),此处表达式中的 "*" 不需要转义符号 "\" 。实例关系运算符实例如下:实例#!/bin/bash# author:华为教程# url:www.huawei.coma=10b=20if [ $a -eq $b ]then echo "$a -eq $b : a 等于 b"else echo "$a -eq $b: a 不等于 b"fiif [ $a -ne $b ]then echo "$a -ne $b: a 不等于 b"else echo "$a -ne $b : a 等于 b"fiif [ $a -gt $b ]then echo "$a -gt $b: a 大于 b"else echo "$a -gt $b: a 不大于 b"fiif [ $a -lt $b ]then echo "$a -lt $b: a 小于 b"else echo "$a -lt $b: a 不小于 b"fiif [ $a -ge $b ]then echo "$a -ge $b: a 大于或等于 b"else echo "$a -ge $b: a 小于 b"fiif [ $a -le $b ]then echo "$a -le $b: a 小于或等于 b"else echo "$a -le $b: a 大于 b"fi执行脚本,输出结果如下所示:10 -eq 20: a 不等于 b10 -ne 20: a 不等于 b10 -gt 20: a 不大于 b10 -lt 20: a 小于 b10 -ge 20: a 小于 b10 -le 20: a 小于或等于 b
-
获得键盘输入会员号。将会员卡号存储在变量中。使用运算符分解会员卡号的个位上的数字。将分解后的数字相加判断是否中奖。首先要使用Scanner的类的方法获得用户从键盘输入的数据。Scanner类是用于扫描输入文本的使用程序。如果使用Scanner类,必须使用import语句导入Scanner类,即指定Scanner类的位置,它将位于java。util包中。(1)导入Scanner类import java.util.*;(2)创建Scanner对象,获得键盘输入的数据Scanner input = new Scanner(System.in):(3)将数据存入变量,输出这个变量.import java.util.Scanner; //导入Scanner类public class Lucky{ public static void main(String[] args){ int custNo; //客户会员号 //输入会员卡号 System.out.println("请输入4位会员卡号:"); Scanner input=new Scanner(System.in); //System.in代表系统输入 custNo=input.nextInt(); //nextInt()获取从键盘输入的一个整数,并赋值给num变量 System.out.println("会员卡号是:"+custNo); }}4位会员卡号和10求余可得个位数4位会员卡号除以10再和10求余可得十位数4位会员卡号除以100再和10求余可得百位数4位会员卡号除以1000可得十位数计算各位之和import java.util.Scanner; //导入Scanner类public class Lucky{ public static void main(String[] args){ int custNo; //客户会员号 //输入会员卡号 System.out.println("请输入4位会员卡号:"); Scanner input=new Scanner(System.in); //System.in代表系统输入 custNo=input.nextInt(); //nextInt()获取从键盘输入的一个整数,并赋值给num变量 System.out.println("会员卡号是:"+custNo); //利用"/"和"%"运算符获得每位数字 int ge=custNo%10; //分解获得个位数 int shi=custNo/10%10; //分解获得十位数 int bai=custNo/100%10; //分解获得百位数 int qian=custNo/1000; //分解获得千位数 System.out.print("千位数:"+qian+",百位数:"+bai+",十位数:"+shi+",个位数:"+ge,); //利用"+"运算符计算数字之和 int sum=ge+shi+bai+qian; System.out.println("会员卡号"+custNo+"各位之和:"+sum); }}10.使用关系运算符中的">"判断import java.util.Scanner; //导入Scanner类public class Lucky{ public static void main(String[] args){ int custNo; //客户会员号 //输入会员卡号 System.out.println("请输入4位会员卡号:"); Scanner input=new Scanner(System.in); //System.in代表系统输入 custNo=input.nextInt(); //nextInt()获取从键盘输入的一个整数,并赋值给num变量 System.out.println("会员卡号是:"+custNo); //利用"/"和"%"运算符获得每位数字 int ge=custNo%10; //分解获得个位数 int shi=custNo/10%10; //分解获得十位数 int bai=custNo/100%10; //分解获得百位数 int qian=custNo/1000; //分解获得千位数 System.out.print("千位数:"+qian+",百位数:"+bai+",十位数:"+shi+",个位数:"+ge,); //利用"+"运算符计算数字之和 int sum=ge+shi+bai+qian; System.out.println("会员卡号"+custNo+"各位之和:"+sum); //判断是否中奖 if(sum>20){ System.out.println("会员卡号"+custNo+"的会员,恭喜您中奖了!奖品是MP4!"); }else{ System.out.println("会员卡号"+custNo+"的会员,很遗憾,您没有中奖!"); } }}
-
什么是设计模式?每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。从面向对象谈起底层思维语言构造编译转换内存模型运行时机制抽象思维面向对象组件封装设计模式架构模式为什么要用设计模式因为软件使用者的需求、技术平台等等都在不断的变化,导致软件要随之变化,最后使得软件的内部结构越来越复杂。而设计模式就是为了解决软件的复杂性而诞生的。如何解决复杂性分解将大问题分解成多个小问题,将复杂问题分解为多个简单问题抽象由于不能掌握全部的复杂对象,我们选择忽视它的非本质细节,而去处理泛化和理想化的对象模型(即设计模式)解析:将具有相同属性的函数从代码中剥离出来,编程一个一个类,他们都继承一个具有相同属性的抽象函数,这个继承结构利用面向对象的多态性,使得主程序在使用时,可以用比之前简短的代码实现一个功能(有多少个子类就有多少种功能,根据需求选择调用哪一种),而且当此功能需要优化时,不需要更改主程序的代码,只需要找到调用的子类,对其进行修改即可,这种方法优异之处在复杂的项目中体现的淋漓尽致。软件设计的金科玉律:复用!重新认识面向对象理解隔离变化从宏观层面来看,面向对象的构建方式更能适应软件的变化,能将变化所带来的影响减到最小。各司其职从微观层面来看,面向对象的方式更强调各个类的“责任”由于需求变化导致的新增类型不应该影响原来类型的实现,而是各负其责对象是什么?从语言实现层面来看,对象封装了代码和数据从规格层面讲,对象是一系列可被使用的公共接口从概念层面讲,对象是某种拥有责任的抽象
-
封装封装是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。继承继承是让某个类获得另一个类的属性和方法。它可以使用现有类的除了私有以外的所有功能,不需要重新编写原来的类的情况下对这些功能进行扩展。多态多态是一个类实例的相同方法在不同情形有不同表现形式,多态机制使具有不同内部结构的对象可以共享相同的外部接口。
-
一. 了解Python的发展历史Python是一种面向对象的解释型计算机程序设计语言,由 吉多·范罗苏姆 开发,第一个公开发行版版发布于 1991 年。它常被昵称为胶水语言,能够把其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起起源:(1)1989年由Guido van Rossum 开发作为ABC语言的继承(2)1991年发布第一个版本(3)Guido 是Monty Python的喜剧团体的爱好者所以命名为 Python历程:(1)2011年1月TIOBE编程语言排行榜评为2010年度语言(2)2014年后Python的使用率一直程线性增长(3)2017年IEEE研究报告显示Python是最受欢迎语言发展:(1)2000年发布Python2.0版本,增加垃圾回收,支持Unicode(2)2008年发布Python3.0版本此版不完全兼容之前的Python源代码(3)2020年官方将不再支持Python2.0版本二. 了解Python 的优缺点2.1 python的优点1、简单,易学:Python是一种代表简单主义思想的语言。阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一。它使你能够专注于解决问题而不是去搞明白语言本身,语法相对简单。2、免费、开源:Python 开源,开发者可以自由的下载,阅读,甚至是修改python源码。3、丰富的第三方库:Python具有本身有丰富而且强大的库,而且由于Python的开源特性,第三方库也非常多,例如:在web开发有django,flask,Tornado、爬虫scrapy、科学计算numpy,pandas等等。4、可以移植:由于Python是开源的,它已经被移植到了大多数平台下面,例如:Windows、MacOS、Linux、Andorid、iOS等等。5、面向对象:Python既支持面向过程,又支持面向对象,这样编程就更加灵活。2.2 python的缺点1、运行速度慢:C程序相比非常慢,因为Python是解释型语言,代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢.而C程序是运行前直接编译成CPU能执行的机器码,所以相对Python而言C语言执行非常快。2、代码不能加密:要发布你写的程序,实际上是发布源代码,而解释型的语言,则必须把源码发布出去.3、强制的缩进:Python有非常严格的缩进语法,只要缩进错误程序立马崩溃。4、GIL全局解释器锁在任意时刻,只有一个线程在解释器中运行。对Python 虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。遇到i/o阻塞的时候会释放掉(GIL)所以Python的多线程并不是真正的多线程,而是CPU执行速度非常快,让人感觉不到GIL的存在。(GIL)会在Python高级阶段讲解。三. 掌握Python数据类型与命名规范命名规范(1)见名知意,尽量使用有语义的单词命名。如使用password用作密码,username 用户名。(2)小驼峰式命名法:第一个单词首字母小写其他单词首字母大写,如userName(3)大驼峰式命名法:全部单词首字母都用大 写 , 如 UserName下划线命名法:每个单词用_下划线连接 , 如user_name四. 掌握Python 基本操作符算术运算符 作用描述 示例+ 加法 算术加法 a + b = 10- 减法 算术减法 a - b = 4* 乘法 算术乘法 a * b = 21** 指数 左边的数是底数,右边是指数 a ** b = 343% 取余 x%y x除以y的余数 a % b = 1/ 除法 x/y 结果包含小数点后面的数 a / b = 2.333333333333335// 地板除 x//y 结果是忽略小数点后面的小数位,只保留整数位 a // b = 2比较运算符 名称 示例 结果描述== 等于 x == y 如果x恰好等于y,则为真!= 不等于 x != y 如果x恰好不等于y,则为真> 大于 x > y 如果x(左侧参数)大于y(右侧参数),则为真< 小于 x < y 如果x(左侧参数)小于y(右侧参数),则为真>= 大于或等于 x >= y 如果x(左侧参数)大于或者等于y(右侧参数),则为真<= 小于或等于 x <= y 如果x(左侧参数)小于或者等于y(右侧参数),则为真逻辑运算符 示例 结果描述and x and y x,y同为真,则结果为真,如果一个为假,则结果为假or x or y x,y有一个为真,则结果为真,全部为假,则结果为假not not x 取反,如果x为真,则结果为假,如果x为假,则结果为真赋值运算符 作用描述 结果描述= 赋值运算符 将=号右边的的值赋值给左边的变量+= 加法赋值运算符 c += a 等效于 c = c + a-= 减法赋值运算符 c -= a 等效于 c = c - a* = 乘法赋值运算符 c *= a 等效于 c = c * a/= 除法赋值运算符 c /= a 等效于 c = c / a%= 取模赋值运算符 c %= a 等效于 c = c % a**= 幂赋值运算符 c **= a 等效于 c = c ** a//= 取整赋值运算符 c //= a 等效于 c = c // a五 .掌握Python 输入与输出import randomprint('BMI体重健康监测')height=float(input('请输入你的身高(米):'))width=float(input('请输入你的体重(kg):'))sum=width/pow(height,2)if sum<18.5: print('过轻')elif sum >= 18.5 and sum <= 25: print('正常')elif sum>=25and sum<=28 : print('过重')elif sum >= 28 and sum <= 32: print('肥胖')elif sum >32 : print('严重肥胖')pass'''输出BMI体重健康监测请输入你的身高(米):12请输入你的体重(kg):34过轻'''
-
题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。程序分析:程序分析:(a>b) ? a:b 这是条件运算符的基本例子。程序源代码:实例(Python 2.x)#!/usr/bin/python# -*- coding: UTF-8 -*-score = int(raw_input('输入分数:\n'))if score >= 90: grade = 'A'elif score >= 60: grade = 'B'else: grade = 'C'print '%d 属于 %s' % (score,grade)实例(Python 3.x)#!/usr/bin/python3score = int(input('输入分数:\n'))if score >= 90: grade = 'A'elif score >= 60: grade = 'B'else: grade = 'C'print ('%d 属于 %s' % (score,grade))以上实例输出结果为:输入分数: 89 89 属于 B
-
一:函数的创建和调用函数的创建:def calc(a,b): c=a+b return cresult=calc(10,20)print(result)二:函数的参数传递位置实参:·根据形参对应的位置进行实参传递关键字实参:·根据形参名称进行实参传递三:函数的返回值例题:输出奇数偶数分好类的def fun(num): odd=[] even=[] for i in num: if i%2: odd.append(i) else: even.append(i) return odd,evenlst=[10,29,34,44,54]print(fun(lst))函数的返回值::如果函数没有返回值[函数执行完毕后,不需要给调用处提供数据]return可以省略不写:函数的返回值,如果是1个,直接返回类型。:函数的返回值,如果是多个,返回的结果为元组。四:函数的参数定义默认值参数:def fun(a,b=10):#b称为默认值参数 print(a,b)#函数的调用fun(100)# 100 10fun(20,30)#20 30函数定义时:给形参设置默认值,只有与形参不符的时候才需要传递实参。个数可变的位置参数:定义函数时,可能无法事先确定传递的位置实参的个数,使用可变的位置参数。使用*定义个数可变的位置形参结果为一个元组def fun(*c): print(*c)fun(10)fun(10,20)fun(100,20,30)输出结果就是:10;10,20;100,20,30;个数可变的关键字形参:定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参,使用**定义个数可变的关键字形参结果为一个字典def fun(**c): print(c)fun(a=10)fun(a=10,b=20)fun(a=100,b=20,c=30)print("hello",'world','chang')函数调用时的参数传递:def fun(a,b,c): print('a=',a) print('b=',b) print('c=',c)fun(10,20,30)结果:a= 10b= 20c= 30如果我们要传一个字典进去的话:def fun(a,b,c): print('a=',a) print('b=',b) print('c=',c)lst=[11,22,33]fun(*lst)结果才会一一对应上。五:递归函数:def fac(n): if n==1: return 1 else: return n*fac(n-1)print(fac(6))递归函数大家应该都很熟悉了,我不介绍了,我只把实现的代码放过来了。斐波那契额数列:def fib(n): if n==1: return 1 elif n==2: return 1 else: return fib(n-1)+fib(n-2)print(fib(6))
-
一、python数据类型转换 要了解python中数据类型转换。 首先,我们需要知道type()这个东西,它可以帮助我们查看变量的数据类型。 它的()里放的就是你要查看的变量的变量名。 然后就是怎么转换数据类型了 在python中,数据类型的转换其实很简单; 要转换成整型,就是------int() 要转换成浮点型,就是-----float() 要转换成字符型,就是-----str() ()里依然是变量名,还有么有其他的方法?作者也暂时不知道,dog.jpg二、python的常见运算符 咱们先设个 X 和 Y 吧,这样比较好举例 算数运算符: 加:X+Y 减:X-Y 乘:X*Y 乘方:X**Y 除法要特别说一下,在数学运算中,除法的公式是------X/Y=A---B(X除以Y等于A余B,注这里这个除发说的不对的话,给我留个言吧) 在python中 X/Y 表示 X除Y(在c中这个可是整除,千万别搞错了) X//Y 表示X整除Y(这个就相当于求上面那个的A) X%Y 表示X对Y求余(这个相当于求B)比较运算符: 大于:X>Y 小于:X<Y 等于:X==Y 大于等于:X>=Y 小于等于:X<=Y 不等于:X!=Y 注:这里这个比较出来的值,返回的是boolean类型的哟(也就是True或False)!!!逻辑运算符: 和:X and Y 或:X or Y 非:X not Y (这其实就是按着英语来的,不会有人连这三个单词都看不懂吧,不会吧不会吧!dog.jpg)附值运算符: X=Y 将Y符给X X+=Y 相当于X=X+Y 将X+Y符给X -= *= /= **=(这四个和上面是一个意思,我就不多说了。)(其实是懒得打字了=。=)三、结尾 python中的数据类型转换和常见的运算符大致就是这么些,有哪些看不明白的可以在评论区回复我,我看到的话能回答的会尽力帮大家解答。这一篇大概就是这么多了,下一篇就讲讲程序控制流程。
-
public:explicit ShardSample(int n);ShardSample(int num, int den);ShardSample(int num, int den, int par, int no_of_samples = 0, int offset = -1);ShardSample(const std::vector<int64_t> &indices);ShardSample(const std::vector<int64_t> &indices, uint32_t seed);~ShardSample() override{};MSRStatus Execute(ShardTaskList &tasks) override;MSRStatus UpdateTasks(ShardTaskList &tasks, int taking);MSRStatus SufExecute(ShardTaskList &tasks) override;int64_t GetNumSamples(int64_t dataset_size, int64_t num_classes) override;在minddata/mindrecord/include/shard_sample.h里面用protected定义的一些变量protected:int numerator_;int denominator_;int partition_id_;int no_of_samples_;std::shared_ptr<ShardShuffle> shuffle_op_;std::vector<int64_t> nums_per_shard_;在minddata/mindrecord/include/shard_sample.h里面用private定义的一些变量private:std::vector<int64_t> indices_;SamplerType sampler_type_;int offset_;minddata/mindrecord/meta/shard_sample.cc全部代码// 导入自定义文件#include "minddata/mindrecord/include/shard_sample.h"// using 声明using mindspore::LogStream;using mindspore::ExceptionType::NoExceptionType;using mindspore::MsLogLevel::ERROR;// 双重命名空间namespace mindspore {namespace mindrecord {/* 由于在shard_sample.h里面已经声明了很多不同传入参数的ShardSample函数所以后续的都是在原有的基础上进行一个深度的定义*/// 在以形参为int n的函数ShardSample里面,对已经定义的变量进行赋值操作ShardSample::ShardSample(int n): numerator_(0),denominator_(0),partition_id_(0),no_of_samples_(n),indices_({}),sampler_type_(kCustomTopNSampler),offset_(-1) {}// 在以形参为int n和int den的函数ShardSample里面,对已经定义的变量进行赋值操作ShardSample::ShardSample(int num, int den): numerator_(num),denominator_(den),partition_id_(0),no_of_samples_(0),indices_({}),sampler_type_(kCustomTopPercentSampler),offset_(-1) {}/* 在以形参为int num, int den, int par, int no_of_samples, int offset的函数ShardSample里面,对已经定义的变量进行赋值操作 */ShardSample::ShardSample(int num, int den, int par, int no_of_samples, int offset): numerator_(num),denominator_(den),partition_id_(par),no_of_samples_(no_of_samples),indices_({}),sampler_type_(kCustomTopPercentSampler),offset_(offset) {}/* 在以形参为const std::vector<int64_t> &indices的函数ShardSample里面对已经定义的变量进行赋值操作 */ShardSample::ShardSample(const std::vector<int64_t> &indices): numerator_(0),denominator_(0),partition_id_(0),no_of_samples_(0),indices_(indices),sampler_type_(kSubsetSampler) {}ShardSample::ShardSample(const std::vector<int64_t> &indices, uint32_t seed) : ShardSample(indices) {sampler_type_ = kSubsetRandomSampler; // SamplerType类型的sampler_type_/* std::make_shared 可以返回一个指定类型的 std::shared_ptrshuffle_op_的类型是std::shared_ptr<ShardShuffle>(智能指针) */shuffle_op_ = std::make_shared<ShardShuffle>(seed); }int64_t ShardSample::GetNumSamples(int64_t dataset_size, int64_t num_classes) {// 检验sampler_type_,返回指定的return值if (sampler_type_ == kCustomTopNSampler) {return no_of_samples_;}// 双重判断if (sampler_type_ == kCustomTopPercentSampler) {if (dataset_size % denominator_ == 0) {return dataset_size / denominator_ * numerator_;} else {return dataset_size / denominator_ * numerator_ + 1;}}// 检查sampler_type_的值,返回indices_的长度if (sampler_type_ == kSubsetRandomSampler || sampler_type_ == kSubsetSampler) {return indices_.size();}return 0;}MSRStatus ShardSample::UpdateTasks(ShardTaskList &tasks, int taking) {if (tasks.permutation_.empty()) { // tasks.permutation_为空ShardTaskList new_tasks;// 创建一个空ShardTaskList列表int total_no = static_cast<int>(tasks.sample_ids_.size());if (sampler_type_ == kSubsetRandomSampler || sampler_type_ == kSubsetSampler) {for (int i = 0; i < indices_.size(); ++i) { // 遍历indices_字符串int index = ((indices_[i] % total_no) + total_no) % total_no;new_tasks.AssignTask(tasks, index); // c和python之间的不同mod结果}} else {int count = 0;if (nums_per_shard_.empty()) { // nums_per_shard_为空/* size_t是一种“整型”类型,里面保存的是一个整数,就像int, long那样,这种整数用来记录一个大小(size)。size_t的全称应该是size type,就是说“一种用来记录大小的数据类型”。通常我们用sizeof(XXX)操作,这个操作所得到的结果就是size_t类型。因为size_t类型的数据其实是保存了一个整数,所以它也可以做加减乘除,也可以转化为int并赋值给int类型的变量。 */for (size_t i = partition_id_ * taking; i < (partition_id_ + 1) * taking; i++) {if (no_of_samples_ != 0 && count == no_of_samples_) break; // 进行围捕,如果溢出,返回开始new_tasks.AssignTask(tasks, i % total_no);count++;}} else {// 获取特定范围内的样本size_t i = partition_id_ - 1 >= 0 ? nums_per_shard_[partition_id_ - 1] : 0;for (; i < nums_per_shard_[partition_id_]; i++) {if (no_of_samples_ != 0 && count == no_of_samples_) break;new_tasks.AssignTask(tasks, i % total_no);count++;}}}ShardTaskList::TaskListSwap(tasks, new_tasks);} else {ShardTaskList new_tasks; // 创建类型为ShardTaskList的列表if (taking > static_cast<int>(tasks.sample_ids_.size())) {return FAILED;}int total_no = static_cast<int>(tasks.permutation_.size());int count = 0;// 获取特定范围内的样本for (size_t i = partition_id_ * taking; i < (partition_id_ + 1) * taking; i++) {if (no_of_samples_ != 0 && count == no_of_samples_) break;new_tasks.AssignTask(tasks, tasks.permutation_[i % total_no]);count++;}ShardTaskList::TaskListSwap(tasks, new_tasks);}return SUCCESS;}MSRStatus ShardSample::Execute(ShardTaskList &tasks) {if (offset_ != -1) {int64_t old_v = 0;int num_rows_ = static_cast<int>(tasks.sample_ids_.size());for (int x = 0; x < denominator_; x++) {// 定义并且根据循环反复计算int samples_per_buffer_ = (num_rows_ + offset_) / denominator_;int remainder = (num_rows_ + offset_) % denominator_;// 对samples_per_buffer_进行运算if (x < remainder) samples_per_buffer_++;if (x < offset_) samples_per_buffer_--;old_v += samples_per_buffer_;// nums_per_shard_ 用于保存当前分片的结束索引nums_per_shard_.push_back(old_v);}}int no_of_categories = static_cast<int>(tasks.categories);int total_no = static_cast<int>(tasks.sample_ids_.size());int taking = 0;if (sampler_type_ == kCustomTopNSampler) { // 非分片案例构造函数 #1no_of_samples_ = std::min(no_of_samples_, total_no);taking = no_of_samples_ - no_of_samples_ % no_of_categories;} else if (sampler_type_ == kSubsetRandomSampler || sampler_type_ == kSubsetSampler) {// 判断参数索引的大小是否大于数据集大小if (indices_.size() > total_no) {MS_LOG(ERROR) << "parameter indices's size is greater than dataset size.";return FAILED;}} else { // 构造函数 TopPercentif (numerator_ > 0 && denominator_ > 0 && numerator_ <= denominator_) {if (numerator_ == 1 && denominator_ > 1) { // 分片taking = (total_no + denominator_ - 1) / denominator_;} else { // 不分片taking = total_no * numerator_ / denominator_;taking -= (taking % no_of_categories);}} else { // 判断是否有参数分子或分母非法MS_LOG(ERROR) << "parameter numerator or denominator is illegal";return FAILED;}}return UpdateTasks(tasks, taking);}MSRStatus ShardSample::SufExecute(ShardTaskList &tasks) {// 双重判断if (sampler_type_ == kSubsetRandomSampler) {if (SUCCESS != (*shuffle_op_)(tasks)) {return FAILED;}}return SUCCESS;}} // 命名空间 mindrecord} // 命名空间 mindspore
-
```C++ std::vector AippSizeFilter(const std::vector &resize_para, const std::vector &crop_para) { std::vector aipp_size; // 特殊情况,其中(没有裁剪和没有调整大小)或(没有裁剪和固定比例调整大小)将导致动态输入 if ((resize_para.size() == 0 || resize_para.size() == 1) && crop_para.size() == 0) { aipp_size = {0, 0}; // 不支持动态输入形状,将生成不完整的 aipp 配置文件。 // 请结帐您的 TensorTransform 输入,src_image_size_h 和 src_image_size 都将为 0 MS_LOG(WARNING) "Dynamic input shape is not supported, incomplete aipp config file will be generated. Please " "checkout your TensorTransform input, both src_image_size_h and src_image_size will be 0"; return aipp_size; } if (resize_para.size() == 0) { // 如果只有 Crop 运算符存在 aipp_size = crop_para; } else if (crop_para.size() == 0) { // 如果仅存在带有 2 个参数的 Resize 运算符 aipp_size = resize_para; } else { // 如果两者都存在 if (resize_para.size() == 1) { aipp_size = crop_para; } else { aipp_size = *min_element(resize_para.begin(), resize_para.end()) *min_element(crop_para.begin(), crop_para.end()) ? resize_para : crop_para; } } #ifdef ENABLE_ACL aipp_size[0] = DVPP_ALIGN_UP(aipp_size[0], VPC_HEIGHT_ALIGN); // H aipp_size[1] = DVPP_ALIGN_UP(aipp_size[1], VPC_WIDTH_ALIGN); // W #endif return aipp_size; } std::vector AippMeanFilter(const std::vector &normalize_para) { // typedef unsigned int == uint32_t std::vector aipp_mean; if (normalize_para.size() == 6) { // 如果 Normalize 运算符存在 std::transform(normalize_para.begin(), normalize_para.begin() + 3, std::back_inserter(aipp_mean), [](uint32_t i) { return static_cast(i / 10000); }); } else { aipp_mean = {0, 0, 0}; } return aipp_mean; } std::vector AippStdFilter(const std::vector &normalize_para) { std::vector aipp_std; if (normalize_para.size() == 6) { // 如果 Normalize 运算符存在 auto zeros = std::find(std::begin(normalize_para), std::end(normalize_para), 0); if (zeros == std::end(normalize_para)) { // typedef unsigned int == uint32_t std::transform(normalize_para.begin() + 3, normalize_para.end(), std::back_inserter(aipp_std), [](uint32_t i) { return 10000 / static_cast(i); }); } else { // 如果 0 出现在 std 向量中 // 在标准向量中检测 0,请验证您的输入 MS_LOG(WARNING) "Detect 0 in std vector, please verify your input"; aipp_std = {1.0, 1.0, 1.0}; } } else { aipp_std = {1.0, 1.0, 1.0}; } return aipp_std; } Status AippInfoCollection(std::map *aipp_options, const std::vector &aipp_size, const std::vector &aipp_mean, const std::vector &aipp_std) { // 几个aipp配置参数 aipp_options->insert(std::make_pair("related_input_rank", "0")); aipp_options->insert(std::make_pair("src_image_size_w", std::to_string(aipp_size[1]))); aipp_options->insert(std::make_pair("src_image_size_h", std::to_string(aipp_size[0]))); aipp_options->insert(std::make_pair("crop", "false")); aipp_options->insert(std::make_pair("input_format", "YUV420SP_U8")); aipp_options->insert(std::make_pair("aipp_mode", "static")); aipp_options->insert(std::make_pair("csc_switch", "true")); aipp_options->insert(std::make_pair("rbuv_swap_switch", "false")); // Y = AX + b,这部分是 A std::vector color_space_matrix = {256, 0, 359, 256, -88, -183, 256, 454, 0}; int count = 0; for (int i = 0; i 3; i++) { for (int j = 0; j 3; j++) { std::string key_word = "matrix_r" + std::to_string(i) + "c" + std::to_string(j); aipp_options->insert(std::make_pair(key_word, std::to_string(color_space_matrix[count]))); ++count; } } // 这部分是 b std::vector color_space_bias = {0, 128, 128}; for (int i = 0; i 3; i++) { std::string key_word = "input_bias_" + std::to_string(i); aipp_options->insert(std::make_pair(key_word, std::to_string(color_space_bias[i]))); } // Y = (X - mean - min) * [std^(-1)],这部分是平均值 for (int i = 0; i aipp_mean.size(); i++) { std::string key_word = "mean_chn_" + std::to_string(i); aipp_options->insert(std::make_pair(key_word, std::to_string(aipp_mean[i]))); } // 这部分是分钟 for (int i = 0; i aipp_mean.size(); i++) { std::string key_word = "min_chn_" + std::to_string(i); aipp_options->insert(std::make_pair(key_word, "0.0")); } // 这部分是 std^(-1) for (int i = 0; i aipp_std.size(); i++) { std::string key_word = "var_reci_chn_" + std::to_string(i); aipp_options->insert(std::make_pair(key_word, std::to_string(aipp_std[i]))); } return Status::OK(); } std::string Execute::AippCfgGenerator() { std::string config_location = "./aipp.cfg"; #ifdef ENABLE_ACL if (info_->init_with_shared_ptr_) { ParseTransforms_(); info_->init_with_shared_ptr_ = false; } std::vector paras; // 记录每个 Ascend 运算符的参数值 for (int32_t i = 0; i ops_.size(); i++) { // 验证运算符 ir json ir_info; if (ops_[i] == nullptr) { MS_LOG(ERROR) "Input TensorOperation[" + std::to_string(i) + "] is null"; return ""; } // 定义运算符名称和参数名称之间的映射 ops_[i]->to_json(&ir_info); // 收集运营商信息 for (auto pos = info_->op2para_map_.equal_range(ops_[i]->Name()); pos.first != pos.second; ++pos.first) { // auto:用来声明自动变量 auto paras_key_word = pos.first->second; paras = ir_info[paras_key_word].get>(); // 尾部插入 info_->aipp_cfg_.insert(std::make_pair(ops_[i]->Name(), paras)); } } std::ofstream outfile; outfile.open(config_location, std::ofstream::out); // 无法打开 Aipp 配置文件,请验证您的系统配置(包括权限) // 在这种情况下,我们将返回代表 Aipp 配置文件位置的空字符串 if (!outfile.is_open()) { MS_LOG(ERROR) "Fail to open Aipp config file, please verify your system config(including authority)" "We will return empty string which represent the location of Aipp config file in this case"; std::string except = ""; return except; } if (device_type_ == MapTargetDevice::kAscend310) { // 处理调整大小参数和裁剪参数以找出输入数据的最终大小 std::vector resize_paras; std::vector crop_paras; // 查找调整大小参数 std::map>::iterator iter; if (info_->aipp_cfg_.find(vision::kDvppResizeJpegOperation) != info_->aipp_cfg_.end()) { iter = info_->aipp_cfg_.find(vision::kDvppResizeJpegOperation); resize_paras = iter->second; } else if (info_->aipp_cfg_.find(vision::kDvppDecodeResizeOperation) != info_->aipp_cfg_.end()) { iter = info_->aipp_cfg_.find(vision::kDvppDecodeResizeOperation); resize_paras = iter->second; } // 查找作物参数 if (info_->aipp_cfg_.find(vision::kDvppCropJpegOperation) != info_->aipp_cfg_.end()) { iter = info_->aipp_cfg_.find(vision::kDvppCropJpegOperation); crop_paras = iter->second; } else if (info_->aipp_cfg_.find(vision::kDvppDecodeResizeCropOperation) != info_->aipp_cfg_.end()) { iter = info_->aipp_cfg_.find(vision::kDvppDecodeResizeCropOperation); crop_paras = iter->second; } if (crop_paras.size() == 1) { crop_paras.emplace_back(crop_paras[0]); } std::vector aipp_size = AippSizeFilter(resize_paras, crop_paras); // 处理归一化参数以找出 Aipp 模块的最终归一化参数 std::vector normalize_paras; if (info_->aipp_cfg_.find(vision::kDvppNormalizeOperation) != info_->aipp_cfg_.end()) { for (auto pos = info_->aipp_cfg_.equal_range(vision::kDvppNormalizeOperation); pos.first != pos.second; ++pos.first) { auto mean_or_std = pos.first->second; normalize_paras.insert(normalize_paras.end(), mean_or_std.begin(), mean_or_std.end()); } } std::vector aipp_mean = AippMeanFilter(normalize_paras); std::vector aipp_std = AippStdFilter(normalize_paras); std::map aipp_options; AippInfoCollection(&aipp_options, aipp_size, aipp_mean, aipp_std); std::string tab_char(4, ' '); outfile "aipp_op {" std::endl; for (auto &option : aipp_options) { outfile tab_char option.first " : " option.second std::endl; } outfile "}"; outfile.close(); } else { //对于案例 GPU 或 CPU outfile "aipp_op {" std::endl "}"; outfile.close(); // 您的运行时环境不是 Ascend310,此配置文件将导致计算结果,请检查。” MS_LOG(WARNING) "Your runtime environment is not Ascend310, this config file will lead to undefined behavior on " "computing result. Please check that."; } #endif return config_location; } bool IsEmptyPtr(std::shared_ptr api_ptr) { return api_ptr == nullptr; } Status Execute::ParseTransforms_() { auto iter = std::find_if(transforms_.begin(), transforms_.end(), IsEmptyPtr); // 您的输入 TensorTransforms 包含至少一个 nullptr,请检查您的输入 if (iter != transforms_.end()) { std::string err_msg = "Your input TensorTransforms contain at least one nullptr, please check your input"; MS_LOG(ERROR) err_msg; RETURN_STATUS_UNEXPECTED(err_msg); } if (device_type_ == MapTargetDevice::kCpu) { (void)std::transform(transforms_.begin(), transforms_.end(), std::back_inserter(ops_), [](std::shared_ptr operation) -> std::shared_ptr { return operation->Parse(); }); } else { for (auto &transform_ : transforms_) { ops_.emplace_back(transform_->Parse(device_type_)); } } return Status::OK(); } Status Execute::validate_device_() { if (device_type_ != MapTargetDevice::kCpu && device_type_ != MapTargetDevice::kAscend310 && device_type_ != MapTargetDevice::kGpu) { // 不支持您的输入设备(选项:CPU 或 GPU 或 Ascend310) std::string err_msg = "Your input device is not supported. (Option: CPU or GPU or Ascend310)"; MS_LOG(ERROR) err_msg; RETURN_STATUS_UNEXPECTED(err_msg); } return Status::OK(); } Status Execute::DeviceMemoryRelease() { // 设备资源为 nullptr,在 Ascend310 情况下是非法的 CHECK_FAIL_RETURN_UNEXPECTED(device_resource_, "Device resource is nullptr which is illegal under case Ascend310"); Status rc = device_resource_->DeviceDataRelease(); if (rc.IsError()) { // 设备数据发布错误 std::string err_msg = "Error in device data release"; MS_LOG(ERROR) err_msg; RETURN_STATUS_UNEXPECTED(err_msg); } return Status::OK(); } ```
-
```C++ // 导入自定义的.h文件 #include "minddata/mindrecord/include/shard_shuffle.h" // 导入系统头文件 #include // 双重命名空间 namespace mindspore { namespace mindrecord { // typedef unsigned int:uint32_t; ShardShuffle::ShardShuffle(uint32_t seed, ShuffleType shuffle_type) // 赋值定义 : shuffle_seed_(seed), no_of_samples_(0), replacement_(false), reshuffle_each_epoch_(true), shuffle_type_(shuffle_type) {} /* typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; typedef long int int64_t; typedef long long int int64_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long int uint64_t; typedef unsigned long long int uint64_t; */ ShardShuffle::ShardShuffle(uint32_t seed, int64_t no_of_samples, bool replacement, bool reshuffle_each_epoch, ShuffleType shuffle_type) : shuffle_seed_(seed), no_of_samples_(no_of_samples), replacement_(replacement), reshuffle_each_epoch_(reshuffle_each_epoch), shuffle_type_(shuffle_type) {} int64_t ShardShuffle::GetNumSamples(int64_t dataset_size, int64_t num_classes) { if (replacement_) { return no_of_samples_ == 0 ? dataset_size : no_of_samples_; // 三目运算符 } return no_of_samples_ == 0 ? dataset_size : std::min(dataset_size, no_of_samples_); // 三目运算符 } MSRStatus ShardShuffle::CategoryShuffle(ShardTaskList &tasks) { uint32_t individual_size; individual_size = tasks.sample_ids_.size() / tasks.categories; // 计算尺寸 std::vector> new_permutations(tasks.categories, std::vector(individual_size)); for (uint32_t i = 0; i tasks.categories; i++) { // 遍历tasks.categories for (uint32_t j = 0; j individual_size; j++) new_permutations[i][j] = static_cast(j); std::shuffle(new_permutations[i].begin(), new_permutations[i].end(), std::default_random_engine(shuffle_seed_)); } tasks.permutation_.clear(); for (uint32_t j = 0; j individual_size; j++) { for (uint32_t i = 0; i tasks.categories; i++) { /* static_cast()通常是安全的。 语言存在有效的转换,或者使之成为可能的适当的构造函数。 唯一有风险的是当您降级为继承的类时。 您必须通过语言外部的方式(例如对象中的标记)确保该对象实际上是您声称的对象的后代 */ tasks.permutation_.push_back(new_permutations[i][j] * static_cast(tasks.categories) + static_cast(i)); } } // static_cast是强制转换成int型 ShardTaskList new_tasks; for (size_t i = 0; i individual_size; ++i) { // 遍历individual new_tasks.AssignTask(tasks, tasks.permutation_[i]); } ShardTaskList::TaskListSwap(tasks, new_tasks); return SUCCESS; } MSRStatus ShardShuffle::Execute(ShardTaskList &tasks) { if (reshuffle_each_epoch_) shuffle_seed_++; if (tasks.categories 1) { return FAILED; } if (shuffle_type_ == kShuffleSample) { // 洗牌每个样本 if (tasks.permutation_.empty() == true) { // 判断是否为空 tasks.MakePerm(); } if (replacement_ == true) { ShardTaskList new_tasks; if (no_of_samples_ == 0) no_of_samples_ = static_cast(tasks.sample_ids_.size()); // 强制转换 if (no_of_samples_ = 0) { // no_of_samples 需要为正 MS_LOG(ERROR) "no_of_samples need to be positive."; return FAILED; } for (uint32_t i = 0; i no_of_samples_; ++i) { // 遍历 new_tasks.AssignTask(tasks, tasks.GetRandomTaskID()); } ShardTaskList::TaskListSwap(tasks, new_tasks); } else { std::shuffle(tasks.permutation_.begin(), tasks.permutation_.end(), std::default_random_engine(shuffle_seed_)); // 从头到尾遍历 auto total_no = static_cast(tasks.Size()); // 强制转换 ShardTaskList new_tasks; size_t samples_to_assign = (no_of_samples_ > 0 && no_of_samples_ total_no) ? no_of_samples_ : tasks.sample_ids_.size(); // 三目运算符 for (size_t i = 0; i samples_to_assign; ++i) { new_tasks.AssignTask(tasks, tasks.permutation_[i]); } ShardTaskList::TaskListSwap(tasks, new_tasks); } } else { // 混洗单元如:(a1, b1, c1),(a2, b2, c2),..., (an, bn, cn) return this->CategoryShuffle(tasks); } return SUCCESS; } } // 命名空间 mindrecord } // 命名空间 mindspore ```
-
```C++ // 导入自定义.h文件 #include "minddata/dataset/kernels/tensor_op.h" // 导入系统标准库文件 #include #include // 双重命名空间 namespace mindspore { namespace dataset { // 名称:计算() // 描述:这个 Compute() 取 1 个 Tensor 并产生 1 个 Tensor。 // 派生类应该覆盖这个函数,否则会出错。 Status TensorOp::Compute(const std::shared_ptr &input, std::shared_ptr *output) { IO_CHECK(input, output); if (!OneToOne()) { // 调用了错误的 Compute() 函数。 这不是 1-1 TensorOp return Status(StatusCode::kMDUnexpectedError, "Wrong Compute() function is called. This is not 1-1 TensorOp."); } else { // 这是 TensorOp 1-1 吗? 如果是,请在派生类中实现这个 Compute()。 return Status(StatusCode::kMDUnexpectedError, "Is this TensorOp 1-1? If yes, please implement this Compute() in the derived class."); } } // 名称:计算() // 描述:这个 Compute() 从不同的列中获取多个张量并产生多个张量。 // 派生类应该覆盖这个函数,否则会出错。 Status TensorOp::Compute(const TensorRow &input, TensorRow *output) { IO_CHECK_VECTOR(input, output); if (OneToOne()) { // op是OneToOne,只能接受一个张量作为输入 CHECK_FAIL_RETURN_UNEXPECTED(input.size() == 1, "The op is OneToOne, can only accept one tensor as input."); output->resize(1); return Compute(input[0], &(*output)[0]); } // 这是 TensorOp 一对一吗? 如果不是,请在派生类中实现这个 Compute()。 return Status(StatusCode::kMDUnexpectedError, "Is this TensorOp oneToOne? If no, please implement this Compute() in the derived class."); } Status TensorOp::Compute(const std::shared_ptr &input, std::shared_ptr *output) { IO_CHECK(input, output); // “调用了错误的 Compute() 函数。这是一个可以执行的运算符的函数” // "不同的设备。如果是,请在派生类中实现。 return Status(StatusCode::kMDUnexpectedError, "Wrong Compute() function is called. This is a function for operators which can be executed by" "different device. If so, please implement it in the derived class."); } Status TensorOp::OutputShape(const std::vector &inputs, std::vector &outputs) { if (inputs.size() != NumInput()) return Status(StatusCode::kMDUnexpectedError, // 输入参数向量的大小与输入数量不匹配 "The size of the input argument vector does not match the number of inputs"); outputs = inputs; return Status::OK(); } Status TensorOp::OutputType(const std::vector &inputs, std::vector &outputs) { if (inputs.size() != NumInput()) return Status(StatusCode::kMDUnexpectedError, // 输入参数向量的大小与输入数量不匹配 "The size of the input argument vector does not match the number of inputs"); outputs = inputs; return Status::OK(); } Status TensorOp::SetAscendResource(const std::shared_ptr &resource) { return Status(StatusCode::kMDUnexpectedError, // 这是一个没有 Ascend Resource 的 CPU 操作符。 请验证您的上下文 "This is a CPU operator which doesn't have Ascend Resource. Please verify your context"); } } // 命名空间 dataset } // 命名空间 mindspore ```
-
方法基本语法基本语法 // 方法定义 public static 方法返回值 方法名称(参数类型 形参){ 方法体代码; return 返回值; } public static void main(String[] args) { // 方法调用 返回值变量 = 方法名称 (实参); }看到这里可能有点抽象,接下来写一个具体的方法:两个整数相加public class TestDemo { // 方法定义 public static int Add(int x,int y){ int sum = x+ y; return sum; } public static void main(String[] args) { //方法的调用 Add(10,20); System.out.println(Add(10,20)); }}注意事项1.方法定义时, 参数可以没有。每个参数要指定类型2.方法定义时, 返回值也可以没有, 如果没有返回值, 则返回值类型应写成 void3.方法定义时的参数称为形式参数(形参),方法调用时的参数称为实际参数(实参)4.方法的定义必须在类之中, 代码书写在调用位置的上方或者下方都可以5.所有程序的入口:main函数形参与实参的关系首先我们写一个交换两个数的方法,并运行一下public class Test1 { public static void swap(int a,int b){ int temp = a; a = b; b = temp; } public static void main(String[] args) { int a = 10; int b = 20; System.out.println("交换实参前:"+a+" "+b); swap(a,b); System.out.println("交换实参后:"+a+" "+b); }}为什么没有发生任何改变呢?因为我们交换的是形参,而不是交换的实参。如果要交换实参,我们应该拿到a和b的地址,但是!a和b在main函数中,函数里的变量属于局部变量,存放在栈上。但是在Java中,拿不到栈上的地址,所以a和b的实际值并没有发生改变。如果要交换a和b的值,只能把a和b的值放在堆上(放在堆上的都是对象!!)
上滑加载中
推荐直播
-
探秘仓颉编程语言:华为开发者空间的创新利器
2025/02/22 周六 15:00-16:30
华为云讲师团
本期直播将与您一起探秘颉编程语言上线华为开发者空间后,显著提升开发效率,在智能化开发支持、全场景跨平台适配能力、工具链与生态完备性、语言简洁与高性能特性等方面展现出的独特优势。直播看点: 1.java转仓颉的小工具 2.仓颉动画三方库lottie 3.开发者空间介绍及如何在空间用仓颉编程语言开发
即将直播 -
大模型Prompt工程深度实践
2025/02/24 周一 16:00-17:30
盖伦 华为云学堂技术讲师
如何让大模型精准理解开发需求并生成可靠输出?本期直播聚焦大模型Prompt工程核心技术:理解大模型推理基础原理,关键采样参数定义,提示词撰写关键策略及Prompt工程技巧分享。
去报名 -
华为云 x DeepSeek:AI驱动云上应用创新
2025/02/26 周三 16:00-18:00
华为云 AI专家大咖团
在 AI 技术飞速发展之际,DeepSeek 备受关注。它凭借哪些技术与理念脱颖而出?华为云与 DeepSeek 合作,将如何重塑产品与应用模式,助力企业数字化转型?在华为开发者空间,怎样高效部署 DeepSeek,搭建专属服务器?基于华为云平台,又该如何挖掘 DeepSeek 潜力,实现智能化升级?本期直播围绕DeepSeek在云上的应用案例,与DTSE布道师们一起探讨如何利用AI 驱动云上应用创新。
去报名
热门标签