الدوال: تعريفها واستدعاؤها
كيف نعطي مجموعة من الأوامر اسمًا، ونستخدمها كلما احتجنا إليها؟
في نهاية هذه المحاضرة ستكون قادرًا على
- تشرح لماذا نكتب الدوال: تقليل التكرار وتسمية الأفكار
- تعرّف دالة من نوع
voidوتستدعيها - تميّز بين المعامل والوسيط، وتمرّر عدة وسائط بالترتيب الصحيح
- تكتب دالة تُرجع قيمة، وتستخدم هذه القيمة داخل تعبير
- تتتبّع الدخول إلى الدالة والخروج منها في المتتبّع، وتقرأ مكدس الاستدعاءات
- تصلح أخطاء المترجم الشائعة في الدوال
محتويات المحاضرة
- الدالة تنهي التكرار وتعطي الفكرة اسمًا
- أنت تستدعي الدوال منذ المحاضرة الأولى
- نعرّف الدالة مرة واحدة ونستدعيها باسمها
- المعامل صندوق في الدالة، والوسيط قيمة تضعها فيه
- المعامل يجعل الدالة الواحدة تصلح لحالات كثيرة
- الوسائط تُسند إلى المعاملات بالترتيب، لا بالاسم
- الأمر
returnيعيد قيمة إلى من استدعى الدالة - الاستدعاء يصلح داخل أي تعبير يقبل قيمته
- الدالة التي تُرجع
booleanتصبح شرطًا مقروءًا - في الدالة عدة أوامر
return، وينفذ منها واحد فقط - الدالة إما أن تنجز عملًا أو تُرجع جوابًا
- كل استدعاء يحصل على إطار خاص وصناديق خاصة به
- الدالة التي تعد بقيمة يجب أن تُرجعها في كل مسار
- الاستدعاء يجب أن يطابق التعريف في الاسم والعدد والنوع
- أسئلة المراجعة
الدالة تنهي التكرار وتعطي الفكرة اسمًا
قلنا في المحاضرة الأولى إن الدالة مجموعة أوامر لها اسم. انظر إلى البرنامج التالي لتعرف لماذا نحتاج إليها: الحلقة نفسها مكتوبة ثلاث مرات.
كم سطرًا ستعدّل؟
شغّل البرنامج. ثم اجعل كل خط من 10 نجوم بدلًا من 20، وعدّ الأماكن التي اضطررت إلى تعديلها.
public class Report {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
System.out.print("*");
}
System.out.println();
System.out.println("Sales report");
for (int i = 0; i < 20; i++) {
System.out.print("*");
}
System.out.println();
System.out.println("Total: 150");
for (int i = 0; i < 20; i++) {
System.out.print("*");
}
System.out.println();
}
}******************** Sales report ******************** Total: 150 ********************
تكتب الأوامر في مكان واحد، وتستخدمها حيثما شئت. وإذا أردت تعديلها عدّلت مكانًا واحدًا.
الاسم printStars يخبرك بما يحدث دون أن تقرأ الحلقة.
أنت تستدعي الدوال منذ المحاضرة الأولى
كتب غيرك هذه الدوال، وأنت تستدعيها باسمها دون أن تعرف تفاصيلها. اليوم ستكتب دوالك بنفسك. لاحظ الأقواس بعد كل اسم: فيها نعطي الدالة ما تحتاج إليه.
| الاستدعاء | ما نعطيها | ما تفعله أو تُرجعه |
|---|---|---|
System.out.println("Hi") | نصًا | تطبعه، ولا تُرجع شيئًا |
input.nextInt() | لا شيء | تُرجع العدد الذي كتبه المستخدم |
Math.pow(2, 3) | عددين | تُرجع 2 مرفوعًا للقوة 3 |
الدالة Math.pow تُرجع قيمة، ونحن نطبعها. ماذا يظهر؟
public class PowerCall {
public static void main(String[] args) {
System.out.println(Math.pow(2, 3));
}
}أظهر الناتج
8.0
لماذا؟ Math.pow تُرجع دائمًا قيمة من نوع double، ولهذا يظهر 8.0 لا 8. الدالة هي التي تحدد نوع ما تُرجعه، وسنحدده اليوم بأنفسنا.
نعرّف الدالة مرة واحدة ونستدعيها باسمها
| الجزء | معناه |
|---|---|
static | مطلوبة الآن في كل دالة نكتبها، وسنشرحها في مساق لاحق. |
void | لا تُرجع هذه الدالة شيئًا |
greet | اسم الدالة، بنمط camelCase مثل المتغيرات |
() | قائمة المعاملات، وهي هنا فارغة |
{ ... } | جسم الدالة: الأوامر التي تنفذها |
أول دالة لك
الدالة greet تقع داخل الصنف وخارج main. شغّل البرنامج، ثم أضف استدعاءً ثالثًا وتوقّع الناتج قبل التشغيل.
public class Greeting {
static void greet() {
System.out.println("Hello!");
System.out.println("Welcome to Java.");
}
public static void main(String[] args) {
greet();
greet();
}
}Hello! Welcome to Java. Hello! Welcome to Java.
عرّفنا دالة لكن هل استدعيناها؟
public class NotCalled {
static void sayBye() {
System.out.println("Bye");
}
public static void main(String[] args) {
System.out.println("Start");
System.out.println("End");
}
}أظهر الناتج
Start End
لماذا؟ يبدأ التشغيل دائمًا من main، أيًا كان ترتيب الدوال في الملف. والتعريف لا ينفذ شيئًا؛ لا تعمل الدالة إلا إذا استُدعيت.
المعامل صندوق في الدالة، والوسيط قيمة تضعها فيه
متغير نصرّح عنه بين قوسي التعريف. هنا name.
static void greet(String name)القيمة التي نكتبها عند الاستدعاء. هنا "Sara".
greet("Sara");تحية لكل اسم
اضغط «تتبّع سطرًا سطرًا»، ثم «دخول» عند كل استدعاء، وراقب الصندوق name يحمل قيمة مختلفة كل مرة. أضف استدعاءً باسمك.
public class GreetByName {
static void greet(String name) {
System.out.println("Hello, " + name + "!");
}
public static void main(String[] args) {
greet("Sara");
greet("Omar");
}
}Hello, Sara! Hello, Omar!
في static void show(int age) والاستدعاء show(19)، ما المعامل وما الوسيط؟
المعامل يجعل الدالة الواحدة تصلح لحالات كثيرة
لنعد إلى التقرير الذي بدأنا به. الحلقة أصبحت في مكان واحد، والطول صار وسيطًا نغيّره كما نشاء.
سطر من النجوم
توقّع الناتج ثم شغّل. غيّر الطول إلى 10 في كل الخطوط، ثم قارن عدد ما عدّلته بما عدّلته في البرنامج الأول.
public class StarReport {
static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
public static void main(String[] args) {
int width = 20;
printStars(width);
System.out.println("Sales report");
printStars(width);
System.out.println("Total: 150");
printStars(width);
}
}******************** Sales report ******************** Total: 150 ********************
مثلث من النجوم
اقرأ عددًا صحيحًا rows، ثم اطبع مثلثًا: السطر الأول نجمة واحدة، والثاني نجمتان، وهكذا حتى rows. استدعِ printStars داخل حلقة. لا تطبع أي رسالة طلب.
import java.util.Scanner;
public class StarTriangle {
static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int rows = input.nextInt();
// Call printStars inside a loop here
}
}3
* ** ***
تلميح 1
عدّاد الحلقة يبدأ من 1 وينتهي عند rows.
تلميح 2
الوسيط هو عدّاد الحلقة نفسه: printStars(i).
الحل
import java.util.Scanner;
public class StarTriangle {
static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int rows = input.nextInt();
for (int i = 1; i <= rows; i++) {
printStars(i);
}
}
}الوسائط تُسند إلى المعاملات بالترتيب، لا بالاسم
معاملان من نوعين مختلفين
نفصل بين المعاملات بفاصلة. اطبع خطًا من 8 علامات =. ثم بدّل ترتيب الوسيطين في أحد الاستدعاءين، واقرأ رسالة المترجم.
public class RepeatSymbol {
static void printLine(char symbol, int count) {
for (int i = 0; i < count; i++) {
System.out.print(symbol);
}
System.out.println();
}
public static void main(String[] args) {
printLine('#', 5);
printLine('-', 3);
}
}##### ---
الدالة نفسها والوسيطان نفسهما، لكن بترتيب مختلف. ماذا يطبع؟
public class ArgumentOrder {
static void divide(int top, int bottom) {
System.out.println(top / bottom);
}
public static void main(String[] args) {
int top = 2;
int bottom = 10;
divide(10, 2);
divide(top, bottom);
}
}أظهر الناتج
5 0
لماذا؟ الوسيط الأول يذهب إلى المعامل الأول دائمًا. في الاستدعاء الثاني top تحمل 2 وbottom تحمل 10، والقسمة بين عددين صحيحين تحذف الكسر فيكون الناتج 0.
الأمر return يعيد قيمة إلى من استدعى الدالة
نكتب نوع القيمة المُرجَعة مكان void. وعند الاستدعاء تحل القيمة المُرجَعة محل الاستدعاء، كما تفعل Math.pow. هذا هو الإرجاع.
int تعني أن الدالة تعد بإرجاع عدد صحيح.
static int max(int a, int b)تُخزَّن القيمة المُرجَعة في متغير لتُستخدم لاحقًا.
int bigger = max(3, 7);الأكبر من عددين
اضغط «تتبّع سطرًا سطرًا»، ثم «دخول» عند سطر max. لاحظ أن الصندوق bigger يظهر في main بعد الخروج من الدالة. اختبر عددين متساويين.
public class MaxOfTwo {
static int max(int a, int b) {
if (a > b) {
return a;
} else {
return b;
}
}
public static void main(String[] args) {
int bigger = max(3, 7);
System.out.println(bigger);
System.out.println(max(10, 4));
}
}7 10
الأمر return ينهي الدالة فورًا. ماذا يطبع البرنامج؟
public class ReturnStops {
static String check(int n) {
if (n > 0) {
return "positive";
}
return "not positive";
}
public static void main(String[] args) {
System.out.println(check(5));
System.out.println(check(0));
}
}أظهر الناتج
positive not positive
لماذا؟ مع 5 يتحقق الشرط، فينتهي التنفيذ عند أول return ولا يصل إلى الثاني. ومع 0 لا يتحقق الشرط، فيصل إلى return الأخير. كل استدعاء يُرجع قيمة واحدة فقط.
الاستدعاء يصلح داخل أي تعبير يقبل قيمته
المساحة في تعبيرات مختلفة
نستخدم القيمة المُرجَعة في إسناد، وفي عملية حسابية، وفي شرط، وفي دمج نص. أضف دالة perimeter تحسب محيط المستطيل واطبعه.
public class RectangleArea {
static double area(double width, double height) {
return width * height;
}
public static void main(String[] args) {
double first = area(3, 4);
double total = first + area(2.5, 2);
System.out.println(total);
if (area(1, 1) < first) {
System.out.println("The first one is bigger");
}
System.out.println("Area: " + area(5, 5));
}
}17.0 The first one is bigger Area: 25.0
كل استدعاء يحل محله ما يُرجعه. ماذا يطبع؟
public class ReturnInExpression {
static int square(int x) {
return x * x;
}
public static void main(String[] args) {
int total = square(3) + square(4);
System.out.println(total);
System.out.println(square(square(2)));
}
}أظهر الناتج
25 16
لماذا؟ 9 + 16 = 25. وفي السطر الأخير يُنفَّذ الاستدعاء الداخلي أولًا فيعطي 4، ثم يصبح وسيطًا للخارجي فيعطي 16.
مساحة المثلث
اكتب الدالة triangleArea التي تأخذ base وheight من نوع double وتُرجع المساحة. يقرأ main العددين، ثم يطبع Area: متبوعًا بالناتج.
import java.util.Scanner;
public class TriangleArea {
// Write the triangleArea method here
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double base = input.nextDouble();
double height = input.nextDouble();
// Call triangleArea and print the result
}
}5 3
Area: 7.5
تلميح 1
المساحة نصف القاعدة في الارتفاع. احذر 1 / 2، فهي تساوي 0 في Java.
تلميح 2
جسم الدالة سطر واحد: return base * height / 2;
الحل
import java.util.Scanner;
public class TriangleArea {
static double triangleArea(double base, double height) {
return base * height / 2;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double base = input.nextDouble();
double height = input.nextDouble();
System.out.println("Area: " + triangleArea(base, height));
}
}الدالة التي تُرجع boolean تصبح شرطًا مقروءًا
هل العدد زوجي؟
اقرأ الشرط بصوت عالٍ: «إذا كان 7 زوجيًا». نكتب الاسم كسؤال يبدأ بـ is، ونُرجع نتيجة المقارنة مباشرة. اكتب دالة isPositive بالطريقة نفسها وجرّبها.
public class EvenCheck {
static boolean isEven(int n) {
return n % 2 == 0;
}
public static void main(String[] args) {
System.out.println(isEven(4));
if (isEven(7)) {
System.out.println("7 is even");
} else {
System.out.println("7 is odd");
}
}
}true 7 is odd
عدّ الأعداد الزوجية
اقرأ عددًا n، ثم استخدم الدالة isEven داخل حلقة لتعدّ الأعداد الزوجية من 1 إلى n. اطبع Evens: متبوعًا بالعدد.
import java.util.Scanner;
public class CountEvens {
static boolean isEven(int n) {
return n % 2 == 0;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
// Count the even numbers from 1 to n, then print the result
}
}6
Evens: 3
تلميح 1
صرّح عن عدّاد count يبدأ من 0 قبل الحلقة.
تلميح 2
داخل الحلقة: if (isEven(i)) { count++; }.
الحل
import java.util.Scanner;
public class CountEvens {
static boolean isEven(int n) {
return n % 2 == 0;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int count = 0;
for (int i = 1; i <= n; i++) {
if (isEven(i)) {
count++;
}
}
System.out.println("Evens: " + count);
}
}في الدالة عدة أوامر return، وينفذ منها واحد فقط
حرف التقدير
استخدم «تتبّع سطرًا سطرًا» و«دخول» مع الاستدعاء gradeLetter(85)، ولاحظ أين تنتهي الدالة. ثم غيّر الوسيط إلى 90 و89، وتوقّع الحرف في كل مرة قبل التشغيل.
public class GradeLetter {
static char gradeLetter(int score) {
if (score >= 90) {
return 'A';
} else if (score >= 80) {
return 'B';
} else if (score >= 70) {
return 'C';
} else if (score >= 60) {
return 'D';
} else {
return 'F';
}
}
public static void main(String[] args) {
System.out.println(gradeLetter(85));
System.out.println(gradeLetter(59));
}
}B F
سعر التذكرة
اكتب الدالة ticketPrice التي تأخذ العمر وتُرجع السعر: أقل من 6 سنوات 0، ومن 6 إلى 17 5، و18 فأكثر 10. يطبع main الطلب Age: ، ثم يقرأ العمر، ثم يطبع Price: والسعر على السطر نفسه.
import java.util.Scanner;
public class TicketPrice {
static int ticketPrice(int age) {
// Replace this line with the rules
return 0;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Age: ");
int age = input.nextInt();
// Print "Price: " and the result of ticketPrice
}
}5
Age: Price: 0
تلميح 1
ابدأ بأصغر الأعمار: if (age < 6)، ثم else if (age < 18).
تلميح 2
لا يظهر ما يكتبه المستخدم في ناتج الاختبار، ولذلك يبدو الطلب والنتيجة متصلين.
الحل
import java.util.Scanner;
public class TicketPrice {
static int ticketPrice(int age) {
if (age < 6) {
return 0;
} else if (age < 18) {
return 5;
} else {
return 10;
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Age: ");
int age = input.nextInt();
System.out.println("Price: " + ticketPrice(age));
}
}الدالة إما أن تنجز عملًا أو تُرجع جوابًا
| وجه المقارنة | void | تُرجع قيمة |
|---|---|---|
| مثال | printStars(5); | int m = max(3, 7); |
| كيف تنتهي | تصل إلى } | تنفذ return مع قيمة |
| أين نستدعيها | في سطر مستقل فقط | داخل تعبير عادةً؛ وفي سطر مستقل تضيع قيمتها |
الدالة twice تحسب وتُرجع. هل تغيّرت x؟
public class DiscardReturn {
static int twice(int n) {
return n * 2;
}
public static void main(String[] args) {
int x = 5;
twice(x);
System.out.println(x);
System.out.println(twice(x));
}
}أظهر الناتج
5 10
لماذا؟ السطر twice(x); يحسب 10 ثم تضيع القيمة لأن أحدًا لم يستخدمها، وx تبقى 5. وفي السطر الأخير تستقبل println القيمة المُرجَعة فتطبعها.
لا شيء لتطبعه
الدالة printStars تطبع بنفسها ولا تُرجع شيئًا، ومع ذلك وضعناها داخل println. أصلح سطر الاستدعاء.
public class VoidPrint {
static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
public static void main(String[] args) {
System.out.println(printStars(3));
}
}'void' type not allowed hereأظهر التصحيح
public class VoidPrint {
static void printStars(int count) {
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
public static void main(String[] args) {
printStars(3);
}
}***
لماذا؟ تحتاج println إلى قيمة تطبعها، ودالة void لا تعطي قيمة. فاستدعِها في سطر مستقل.
تريد دالة تحسب معدل الطالب ليستخدمه main في شرط. ما النوع المناسب لما تُرجعه؟
main، فلا يستطيع استخدامها في شرط. والمعدل فيه جزء عشري، فيناسبه double.كل استدعاء يحصل على إطار خاص وصناديق خاصة به
عند الاستدعاء ينتقل التنفيذ إلى الدالة وينتظر المستدعي، وعند انتهائها يعود إليه ليكمل. ويحتفظ البرنامج بسلسلة الاستدعاءات الجارية في مكدس الاستدعاءات (call stack): لكل استدعاء إطار (frame) فيه متغيراته، وأحدث إطار في الأعلى.
ادخل واخرج بنفسك
توقّع الناتج، ثم اتبع الخطوات أدناه باستخدام أزرار المتتبّع.
public class CallStack {
static int square(int x) {
int result = x * x;
return result;
}
static int sumOfSquares(int a, int b) {
int first = square(a);
int second = square(b);
return first + second;
}
public static void main(String[] args) {
int answer = sumOfSquares(3, 4);
System.out.println(answer);
}
}25
- اضغط «تتبّع سطرًا سطرًا»يتوقف عند أول سطر في
main، وفي المكدس إطار واحد:main(). - اضغط «دخول» (F7)يظهر الإطار
sumOfSquares()فوقmain()، وفيه الصندوقانa = 3وb = 4. - اضغط «دخول» مرة أخرىيظهر الإطار
square()في الأعلى وفيهx = 3. الآن في المكدس ثلاثة إطارات. - اضغط «خروج من الدالة» (Shift+F8)يختفي الإطار
square()وصناديقه، ويظهرfirst = 9فيsumOfSquares(). - اضغط «السطر التالي» (F8)يُنفَّذ الاستدعاء الثاني كاملًا دون الدخول إليه، ويظهر
second = 16. - اضغط «خروج من الدالة» ثم «متابعة» (F9)تعود إلى
mainومعهاanswer = 25، ثم يكمل البرنامج حتى النهاية.
توقف المتتبّع عند السطر int result = x * x; في البرنامج أعلاه. ما الإطار الذي في أعلى المكدس؟
square، بينما ينتظر sumOfSquares وmain تحته.تتبّع التنفيذ بإصبعك من main. ماذا يطبع؟
public class FlowOrder {
static void middle() {
System.out.println("B");
}
public static void main(String[] args) {
System.out.println("A");
middle();
System.out.println("C");
middle();
}
}أظهر الناتج
A B C B
لماذا؟ بعد انتهاء كل استدعاء يعود التنفيذ إلى السطر الذي يلي الاستدعاء في main، فتُطبع B مرتين، مرة لكل استدعاء.
الدالة التي تعد بقيمة يجب أن تُرجعها في كل مسار
مسار بلا return
ماذا تُرجع الدالة إذا كان a أصغر من b أو يساويه؟ أكمل الدالة لتعمل مع كل الحالات.
public class MissingReturn {
static int max(int a, int b) {
if (a > b) {
return a;
}
}
public static void main(String[] args) {
System.out.println(max(2, 8));
}
}missing return statementأظهر التصحيح
public class MissingReturn {
static int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
public static void main(String[] args) {
System.out.println(max(2, 8));
}
}8
لماذا؟ يتأكد المترجم أن كل طريق داخل الدالة ينتهي بقيمة. وإذا كان الشرط خطأ هنا تصل الدالة إلى نهايتها دون قيمة. لاحظ أن الرسالة تشير إلى } الأخيرة في الدالة، لأن المشكلة هي وصول التنفيذ إليها.
هل تُترجم هذه الدالة؟
static int larger(int a, int b) {
if (a >= b) {
return a;
}
if (a < b) {
return b;
}
}
if قد لا تنفذ، فيعدّ نهاية الدالة قابلة للوصول. استخدم else أو return أخيرة.الاستدعاء يجب أن يطابق التعريف في الاسم والعدد والنوع
عدد الوسائط خطأ
الدالة تحتاج إلى وسيطين، ونحن أعطيناها واحدًا. أضف الارتفاع 4.
public class WrongCount {
static int area(int width, int height) {
return width * height;
}
public static void main(String[] args) {
System.out.println(area(3));
}
}cannot be applied to given typesأظهر التصحيح
public class WrongCount {
static int area(int width, int height) {
return width * height;
}
public static void main(String[] args) {
System.out.println(area(3, 4));
}
}12
لماذا؟ يكمل المترجم الرسالة بسطرين: required وهو ما تطلبه الدالة، وfound وهو ما أعطيته. قارن بينهما لتعرف ما ينقص.
نوع الوسيط خطأ
علامتا التنصيص جعلتا الوسيط نصًا. أصلح الاستدعاء.
public class WrongType {
static int twice(int n) {
return n * 2;
}
public static void main(String[] args) {
System.out.println(twice("21"));
}
}incompatible types: String cannot be converted to intأظهر التصحيح
public class WrongType {
static int twice(int n) {
return n * 2;
}
public static void main(String[] args) {
System.out.println(twice(21));
}
}42
لماذا؟ إسناد الوسيط إلى المعامل يشبه الإسناد العادي: الصندوق int n لا يقبل نصًا. لذلك تشبه الرسالة ما رأيناه في int age = "19";.
دالة غير معرّفة
حرف واحد يفرق بين الاسمين. أصلح الاستدعاء.
public class Undefined {
static void printLine() {
System.out.println("-----");
}
public static void main(String[] args) {
printline();
}
}cannot find symbolأظهر التصحيح
public class Undefined {
static void printLine() {
System.out.println("-----");
}
public static void main(String[] args) {
printLine();
}
}-----
لماذا؟ Java تميز بين الحروف الكبيرة والصغيرة، فالاسم printline ليس printLine. وهي الرسالة نفسها التي تظهر مع متغير غير معرّف، والسطر symbol: فيها يدلك على الاسم الذي لم يجده المترجم.
أسئلة المراجعة
ماذا تعني void في تعريف الدالة؟
void بما يخرج من الدالة فقط. أما ما يدخل إليها فتحدده المعاملات بين القوسين، ودالة void قد تأخذ معاملات مثل printStars(int count).في ملف كتبنا فيه خمس دوال قبل main، من أين يبدأ التشغيل؟
main، ولا تعمل الدوال الأخرى إلا باستدعائها.تتبّع على الورق، ثم تأكد باستخدام «تتبّع سطرًا سطرًا».
public class ReviewTrace {
static int addOne(int n) {
return n + 1;
}
static void show(int n) {
System.out.println("n = " + n);
}
public static void main(String[] args) {
int value = addOne(4);
show(value);
show(addOne(value) * 2);
}
}أظهر الناتج
n = 5 n = 12
لماذا؟ value تساوي 5. ثم addOne(5) تعطي 6، وتُضرب في 2 فتكون 12 قبل أن تصبح وسيطًا لـ show.