Професионална програма
Loading...
+ Нов въпрос
VesselinTonchev avatar VesselinTonchev 4 Точки

Предаване на стойност по референция/променлива

Здрасти, банда!

Имам леко неразбиране на това как обекти си предават стойности м/у отделните методи. Доколкото разбирам от лекторите, масивите и списъците са референтни типове данни. Аз това го разбирам - не е нужно да използваш ref, за да прехвърлиш стойност м/у два и повече метода. Може да не съм го разбрал правилно, защото от кода долу очаквах bigger да си вземе коректно стойността. Оказа се, че, ако ref липсва, каквото и да правя bigger си взима по - ниската стойност??? Гледах го с дебъгера и реших проблема, като му казах, че е референция. Някой ще може ли да ми обясни защо работи така, тъй като не знам как да си формулирам въпроса към д-р Google?

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

namespace FUCKING_LISTS_Lab
{
    class Program
    {
        static List<int> ListLengthChecker(ref List<int> bigger, ref List<int> smaller, ref List<int> temp)
        {
            if (smaller.Count > bigger.Count)
            {
                temp = bigger;
                bigger = smaller;
                smaller = temp;

                return bigger;
            }
            else
            {
                return bigger;
            }            
        }
        static void Main(string[] args)
        {
            List<int> smaller = Console.ReadLine().Split().Select(int.Parse).ToList();
            List<int> bigger = Console.ReadLine().Split().Select(int.Parse).ToList();

            List<int> temp = new List<int>();

            ListLengthChecker(ref bigger, ref smaller, ref temp);

            for (int i = 0; i < smaller.Count; i++)
            {
                bigger.Add(smaller[i]);
            }

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

 

Тагове:
0
Module: C# Advanced
kkaraivanov avatar kkaraivanov 427 Точки

Здравей. Неразбирам какво точно искаш да направиш с този код. ref се ползва за нереферентни типове, а List е референтен тип. Когато присвояваш списък на друг списък, за да вземеш стойностите и да имаш нов списък е необходимо да ползваш ToList(). По този начин имаш 2 различни списъка. В метода си присвояванията които правиш водят до резултат от три листа с една и съща стойност - тази на smaller. В Main където искаш да ползваш метода си понеже той е лист трябва да го присвоиш на друг лист или да го изпишеш на конзолата. Така както си го изписъл нищо няма да се случи.

 

Edit: Виждам, че се опитваш да прехвърлиш стойностите от единия в другия масив. Редактирах кода ти и работи коректно

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

namespace FUCKING_LISTS_Lab
{
    class Program
    {
        static void ListLengthChecker(List<int> bigger, List<int> smaller)
        {
            List<int> temp = bigger.ToList();
            bigger.Clear();
            bigger.AddRange(smaller);
            smaller.Clear();
            smaller.AddRange(temp);
        }

        static void Main(string[] args)
        {
            List<int> smaller = Console.ReadLine().Split().Select(int.Parse).ToList();
            List<int> bigger = Console.ReadLine().Split().Select(int.Parse).ToList();

            if (smaller.Count > bigger.Count)
                ListLengthChecker(bigger, smaller);
            
            for (int i = 0; i < smaller.Count; i++)
            {
                bigger.Add(smaller[i]);
            }

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

В отговор на въпроса ти, както казах по-горе ref е за не референтни типове, което ще рече че List реферира bigger и smaller като адреси в паметта, а ref - стойностите в листовете и това е причинада метода ти да има поведение на void метод.

0
02/03/2020 13:11:16
nickwork avatar nickwork 609 Точки

Привет, първо искам да те попитам коя е тази задача, ако можеш дай някакво условие..

Второ - съветвам те на този етап изобщо да не използваш реф, това е излишно, просто запомни, че всички примитивни типове данни (такива като инт, стринг...напиши това в google че да не ги изброявам всичките c# primitive data types)  не са рефернтни типове. Потърси в инет какво е референтен тип данни - накратко когато създаваш една променлива тя отделя място в паметта към която СОЧИ към определн адрес в паметта например int[] a = {1,2,3,4,5}, ако кажа че int[] b = a / в паметта на комп не се създава нова памет, нов адрес за този нов масив -  int[] b / а той започва да СОЧИ към мястото в паметта на компа където е записан int[] a = {1,2,3,4,5} - именно заради това че сочат към едно място в паметта на компа при промяна да кажем на int[] a = {1,2,3,4,5} с други стойности ние автоматично променяме и int[] b;

При простите типове от данни всеки път се заделя ново място в паметта на компа при създаване на нова променлива - именно заради това, че при простите те не сочат към една и съща памет (даже да имат еднакви стойности например a = 5; b = a; a = 10) променливата b не се променя а остава със стойност 5(тествай го, защото не реферира към паметта на променливата "а",  а се създава ново място в паметта на компа с новата стойност).

В този код който си написал си създал List<int> temp който по никакъв начин не използваш и е излишен.

Като съвет - потърси в youtube някакво видео (на разбираем за теб език) за примери и обяснения

1. c# primitive data types

2.c# reference data types

и ако искаш дай някакво условие аз ще ти я разпиша задачата както трябва след това да я дебъгнеш.

 

0
VesselinTonchev avatar VesselinTonchev 4 Точки

Аз мисля, че вече ми помогнахте. Създавам празен лист, но после не му присвоявам нищо и той си озтава така, а през цялото време работя с оригиналните колекции - тъпо. Това исках да разбера, защо не си присвоявам променливата от метода, който ми върши операциите. Нещо в синтаксиса ми бяга, явно :) Иначе задачата е много проста, просто исках да тренирам методите - 1.   Merging Lists от Lists - Lab.

0
nickwork avatar nickwork 609 Точки

Eто ти едно интересно решение на тази задача... направи следното - маркирай целият фор цикъл и натисни ALT + ENTER - ще ти искочи едно меню...разгледай го ще разбереш какво да правиш - по този начин си тренирай създаването на методи - забележи visual studio как ги създава и след това се пробвай сам

 

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

namespace Merging_Lists
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> firstList = Console.ReadLine()
                .Split()
                .Select(int.Parse)
                .ToList();

            List<int> secondList = Console.ReadLine()
                .Split()
                .Select(int.Parse)
                .ToList();

            List<int> rezult = new List<int>();

            for (int i = 0; i < Math.Max(firstList.Count, secondList.Count); i++)
            {
                if(i < firstList.Count)
                {
                    rezult.Add(firstList[i]);
                }

                if(i < secondList.Count)
                {
                    rezult.Add(secondList[i]);  
                }
            }
            Console.WriteLine(string.Join(" ", rezult));
        }
    }
}

0
VesselinTonchev avatar VesselinTonchev 4 Точки

btw, така, както е показано, всеки път във for цикъла ще трябва да изчислява  Math.Max, но иначе разбрах :D Много Благодаря!

0