משתנה (תכנות)

בתכנות, משתנה (באנגלית: Variable) הוא חלק זיכרון בתוכנית המכיל נתון שיכול להשתנות בזמן הריצה, על פי הפקודות הניתנות לו, בניגוד לקבוע שמכיל ערך שנקבע בתחילת ההרצה ונשאר קבוע עד סופה. גודל המשתנה עצמו שונה לפי סוג הטיפוס שלו ויכול לנוע מסיבית אחת ועד טווח זיכרון גדול של מגהבייטים שלמים. בנוסף לפעולת ההשמה ניתן לבצע גם פעולה של שליפת המידע שבמשתנה.

==שמות==
לכל משתנה חייב להיות שם. שם משתנה יכול להכיל רצף מכל סוג שהוא של אותיות ומספרים. ישנם תווים בודדים שאסור שיהיו בשם משתנה או בתחילתו. לצורך קריאות הקוד ישנן שיטות שונות לקבוע את שמות המשתנים. אחת הידועות שבהן היא "השיטה ההונגרית", בה המקדמים בכל שם מצביעים על הטיפוס שלו. אחד הדברים החשובים בהבנת קוד תוכנית הוא נתינת שמות משתנים משמעותיים וארוכים, שמסבירים את תפקידו של המשתנה בעצם שמו. לעיתים ישנן מוסכמות לקידומת של משתנה בהתאם לסוגו, ולטווח הכרתו. הדבר נפוץ בעיקר בהגדרת פקדים בטפסים, ומאפשר לנווט ביניהם בקלות.

בשפות תכנות ישנות (למשל BASICA) היה מקובל להשתמש בשמות קצרים מאוד (לרוב אות אחת), כיום גישה זו איננה מקובלת. במרבית שפות התכנות המודרניות, שמות המשתנים חייבים להיות מזהים חוקיים, כלומר הם מוגבלים על פי אותם חוקים המגבילים את שמות הפונקציות, המחלקות, הקבועים וכדומה. מגבלות אלו משתנות משפת תכנות אחת לשנייה אולם הם לרוב כוללות מגבלת תווים אפשריים (תווים המשתמשים לאופרטורים כמו + או ? לרוב אסורים), איסור על שמות הזהים למילים שמורות וכן מספר תווים משמעותיים (למשל ב-Embedded SQL משתנים שהם בעלי 31 תווים ראשונים זהים נחשבים זהים).

בחלק משפות התכנות לכל שם משתנה מוצמד תג המציין את סוגו, כך למשל המשתנים <span style="direction: ltr;">&lrm;$Wikipedia, @Wikipedia, %Wikipedia</span> הם משתנה סקלרי, מערך ו-Hash ב-Perl שאינם מושפעים אחד מהשני (הגם שניתן לגשת לכולם באמצעות Wikipedia*).

ישנן מספר שיטות מקובלות לשמות משתנים, התלויות בשפת התכנות (במיוחד בשאלה האם היא מבחינה בין אותיות קטנות לגדולות) ובספריות בהן משתמשים, כך ניתן למצוא שדה של אובייקט בעל השמות m_WikipedaCount, wikipediaCount, wikipediaCount_, wikipedia_count ועוד.

==הכרזה מפורשת והכרזה מרומזת==
בחלק משפות התכנות כמו שפת C ושפת Pascal, חובה להכריז על המשתנה לפני השימוש בו. שימוש במשתנה בלי הכרזה מפורשת שלו תגרום להודעת שגיאה. שפות אחרות, בעיקר שפות סקריפט כמו VBScript לא דורשות מן התוכניתן להכריז על המשתנה בטרם השימוש בו, והמערכת מגדירה אותו בפעם הראשונה שהיא נתקלת בו. אם כי על פי נוהלי התכנות המתוקנים, רצוי להכריז על כל המשתנים באופן מאורגן, והדבר תורם לסדר של הקוד, איתור שגיאות כתיב, ולניפוי יעיל של הקוד. ישנן שפות שיש בהן את שתי האפשרויות, לעבוד במוד של הכרזה מפורשת והכרזה מרומזת. לעיתים הדבר נאכף על ידי המהדר על פי סוג ההצהרה בתחילת המודול (למשל use strict ב-Perl).

==סוג טיפוס==

לכל משתנה יש טיפוס שקובע איזה סוג נתונים הוא יכול להכיל, ולמעשה, מהי קבוצת הערכים שאליה יהיה שייך כל ערך של המשתנה. גודל המשתנה שונה בהתאם לטיפוס ויכול להיות בטווח רחב. גודל קטן ביותר למשתנה מסוג בוליאני ותו ועד לגודל גדול למשתנה מסוג מערך או אובייקט.

סוגים טיפוסיים של משתנים הם: מספר שלם (בטווחים שונים), מספר ממשי - (נקודה צפה) (בטווחים שונים), תו, מחרוזת, מערך, מצביע, רשומה, אובייקט וערך בוליאני, ישנן שפות שמוסיפות טיפוסים ספציפיים נוספים כמו משתני אוסף, תאריך ומטבע. ברוב השפות ניתן גם להגדיר טיפוסים חדשים על ידי הרכבה (קומפוזיציה) של טיפוסים אחרים, או שימוש בבנאים (לא להתבלבל עם קונסטרקטורים בתכנות מונחה עצמים!) כגון תבניות בC++.

==אורך חיים==
אורך חיים הוא פרק הזמן בריצת התוכנית שבו המשתנה נשמר בזיכרון.
משתנה גלובלי יהיה קיים כל זמן שהתוכנית רצה. משתנה מקומי המוגדר בפונקציה יהיה קיים בזמן שהפונקציה מורצת, אך לפניה או אחריה הוא לא יהיה קיים כלל (למעט בשפות בהן ניתן להגדיר משתנה סטטי ששומר על ערכו) בפעם הבאה שבה תתבצע התייחסות אליו, זה כבר יהיה משתנה אחר לחלוטין. משתנה גלובלי במחלקה יהיה קיים כאשר נוצר מופע של המחלקה.

==טווח הכרה==
טווח ההכרה הוא הטווח שבו המשתנים חשופים בתוך התוכנית.
ישנם שלושה סוגים עיקריים של טווח הכרה במשתנים:
#משתנים גלובליים - מוכרים בכל התוכנית.
#משתנים לוקליים - מוכרים בבלוק או בשגרה שהגדירה אותן.
#הכרה דינמית - למשל בזריקת חריגות, המשתנה "נזרק" באזור אחד בקוד, וניגשים אליו במקום אחר לחלוטין.

==אתחול==
בחלק מהשפות כמו למשל C, ניתן לאתחל את המשתנה לערך מסוים, אחרת עלול להימצא בו "זבל" (שהוא ערך מספרי מקרי, שנמצא בזיכרון המחשב, עקב פעולות קודמות). בשפות אחרות נעשה אתחול אוטומטי בזמן היצירה של המשתנה, כך שמשתנה מספרי מאופס, משתנה מחרוזתי מאותחל למחרוזת ריקה, משתנה מצביע מאותחל למיקום לא קיים וכדומה. וישנן שפות, כגון פסקל בהן אין דרך לאתחל משתנה בעת ההצהרה עליו. בשפות בהן לא קיים אתחול אוטומטי, הדבר מאפשר גמישות ומניח למתכנת לבחור באתחול או לוותר עליו, מכיוון שלפעמים אין צורך באתחול והדבר מבזבז פעולות חישוב, במיוחד כאשר מדובר במשתנים רבים. החיסרון שבחוסר אתחול אוטומטי שתמיד המתכנת צריך לדאוג לערכים שבמשתנה, ולעיתים אי תשומת לב מספקת לעניין, עלולה לגרום לבאגים קשים לאיתור.

==שימוש==
על כל משתנה ניתן לבצע שתי פעולות: פעולת השמה של ערכים לתוכו, ופעולה של שליפת מידע הנתון בו. בדרך כלל ניתן לבצע פעולות השמה למשתנה, כאשר הנתונים המושמים בו, הם מסוג הטיפוס של המשתנה. פעולות על המשתנים יבוצעו בדרך כלל באמצעות אופרטורים שונים. 

דוגמה שכוללת את שתי הפעולות היא למשל חישוב מתמטי של ערכים שנעשה בין משתנים שונים. בדוגמה הבאה: 
<blockquote style="border:1px solid blue; padding:1px; direction:ltr;">
A=B+C </blockquote> התוכנה תשלוף את הנתון שקיים במשתנה C תחבר אותו לערך שקיים במשתנה B, ותבצע השמה של הערך החדש לתוך משתנה A. מכיוון שהפעולה המתמטית נעשית באופן הזה (מימין לשמאל), ערך התוצאה יהיה מוגבל לא רק לפי ערכו של משתנה A אלא גם לפי ערכו של משתנה B. במקרה שמשתנה B יהיה מטיפוס קטן יחסית למשתנה C, הערך יוגבל לפיו. למשל אם משתנים C וA הם מטיפוס נקודה צפה ומשתנה B הוא מספר שלם, התוצאה ב-A תמיד תהיה מספר שלם. 

במקרה של השמת נתונים מטיפוס אחר מסוג המשתנה, לעיתים תתבצע שגיאת הידור ולעיתים תתבצע פעולת המרה באופן אוטומטי בהתאם לסוג הטיפוס, לשפת התכנות ולמהדר.
כאשר נעשה ניסיון לבצע השמת מחרוזת למשתנה מטיפוס מספרי לרוב הדבר יהיה כרוך בהודעת שגיאה. לעומת זאת כאשר תתבצע השמה של מספר נקודה צפה (שבר) למספר שלם, יתבצע חיתוך של השארית, והתוכנה תמשיך לרוץ כרגיל. גם במקרה של השמה של מספר גדול למשתנה קטן שלא יכול להכיל אותו לא תופיע שגיאה, ותתבצע גלישה של המספר. דברים הפותחים פתח לבאגים של טעויות ואי דיוק חישובי, שקשה לנפות אותם לעומת באגים אחרים.

באמצעות משתנים ניתן לבצע פעולות חישוב שונות, גם בלי השמה למשתנה אחר או שליפה מפורשת. משתנים יכולים להופיע בהתניה לוגית. למשל <blockquote style="border:1px solid blue; padding:1px; direction:ltr;">
If A+b > 5 then beep </blockquote> שמשמעותה (ב-BASIC) להשמיע צפצוף במקרה שצירוף הערכים שבמשתנים A ו-B גדול מ-5. במקרה זה בזמן ביצוע התנאי מתבצעת פעולה של חיבור הערכים שבמשתנים A ו-B באופן זמני והשוואה לערך של הקבוע 5. משתנים אלו ישמרו על ערכם ללא כל שינוי.

האינטראקציה בפעולות חישוביות איננה חייבת להיות רק בין משתנים, והיא יכולה להיות בין משתנה לקבוע ואף בין משתנה לפונקציה. כך למשל ניתן לבצע השמה של ערך שמוחזר מפונקציה + ערך של משתנה למשתנה אחר. לדוגמה 
<blockquote style="border:1px solid blue; padding:1px; direction:ltr;">
A=B+MaxOf(C,D) </blockquote> שמשמעותו השם למשתנה A את הערך שבמשתנה B + את הערך שמוחזר מהפונקציה MaxOf כאשר הפונקציה מקבלת שני ערכים ומחזירה את הגדול שבהם.

==דוגמאות של הגדרת משתנים==
דוגמאות להגדרת משתנה בשם A מסוג Integer ואתחול שלו בערך 5 בשפות תכנות שונות. ישנן שפות שחייבת להיות מילת קידומת מסוימת על מנת להכריז על משתנה כמו Var (קיצור של Variable) בפסקל ו-DIM (או Public או Private) ב-VB, וישנן שפות שבהן אין כתיבה של מילה קבועה, אלא כתיבת סוג הטיפוס עצמו לפני משתנה היא הוראה ליצירת משתנה.

===פסקל===
<syntaxhighlight lang="pascal"> 
Var a: Integer=5;
</syntaxhighlight> 

===C ו-C++===
<syntaxhighlight lang="cpp"> 
int a = 5;
</syntaxhighlight> 

===VB===
<syntaxhighlight lang="vb"> 
Dim a As Integer=5
</syntaxhighlight>

=== JavaScript ===
<syntaxhighlight lang="javascript">
var a = 5
</syntaxhighlight>
או:
<syntaxhighlight lang="javascript">
 a = 'variable'
</syntaxhighlight>

== ראו גם ==
* מצביע
* מילה שמורה

קטגוריה:תכנות
קטגוריה:מבני נתונים
קטגוריה:שפות תכנות