Announcement

Collapse
No announcement yet.

con trỏ trong C phần 2 - và các phần tiếp theo

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Ansi C] con trỏ trong C phần 2 - và các phần tiếp theo

    phần tiếp theo của bài viết " con trỏ trong C".
    đoạn code:
    PHP Code:
    #include<stdio.h>
    #include<conio.h>

    void Tag(int *a)
    {
        
    a=new int();
    };
    int main()
    {
        
    int *p=NULL;
        
    Tag(p);
        *
    p=6;

        
    printf("%d", *p);
        
    getch();
        return 
    0;

    hỏi: khi chạy chương trình thì kết quả như thế nào, giải thích tại sao có kết quả như vậy và đưa ra giải pháp nếu có.
    xin các bạn lưu ý là mình chỉ thảo luận về con trỏ, những nội dung khác không liên quan đến phần này, xin viết ở topic khác.
    Last edited by 11520327; 06-10-2012, 09:01.

  • #2
    Theo mình chương trình nay lỗi.
    Muốn in ra giá trị 6, thì phỉa ntn:
    void Tag(int **a)
    {
    (*a) = new int();
    }
    or
    void Tag(int* &a)
    {
    a = new int();
    }

    Comment


    • #3
      void Tag(int **a)
      {
      (*a) = new int();
      }
      nếu bạn viết hàm như thế này thì phải sửa lại cách gọi hàm Tag(&p) trong hàm main.
      void Tag(int* &a)
      {
      a = new int();
      }
      hàm này viết đơn giản hơn hàm trên, hiệu quả tương tự.
      phần giải thích đâu a? tại sao đoạn code đầu sai, tại sao 2 giải pháp trên đúng?
      Last edited by 11520327; 04-10-2012, 10:32.

      Comment


      • #4
        Originally posted by 11520327 View Post
        phần tiếp theo của bài viết " con trỏ trong C".
        đoạn code:
        PHP Code:
        #include<stdio.h>
        #include<conio.h>

        void Tag(int *a)
        {
            
        a=new int();
        };
        int main()
        {
            
        int *p=NULL;
            
        Tag(p);
            *
        p=6;

            
        printf("%d", *p);
            
        getch();
            return 
        0;

        hỏi: khi chạy chương trình thì kết quả như thế nào, giải thích tại sao có kết quả như vậy và đưa ra giải pháp nếu có.
        xin các bạn lưu ý là mình chỉ thảo luận về con trỏ, những nội dung khác không liên quan đến phần này, xin viết ở topic khác.
        Chương trình của bạn bị lỗi.
        Nếu kiểu của đối số và kiểu của tham số truyển vào khi gọi hàm là giống nhau thì bạn đã truyển tham trị chứ không phải truyền tham chiếu, ở đây khi bạn gọi hàm Tag(p) tức là bạn đã truyền tham trị, những gì thực hiện trong hàm Tag sẽ không ảnh hưởng gì đến p, do đó khi thực hiện đến lệnh tiếp theo là *p=6 sẽ bị báo lỗi.

        Comment


        • #5
          vậy 2 hàm anh đưa ra giải thích sao đây?

          Comment


          • #6
            Code đầu:
            void Tag(int *a)
            {
            a=new int();
            };
            -> cấp phát như vậy tức là cấp phát cho biến con trỏ cục bộ (chứ ko phải cấp phát cho biến truyền vào), ra khỏi hàm biến con trỏ cục bộ bị hủy. Thế nên biến truyền vào chưa đc cấp phát :happy:
            Code sau: cấp phát như mình, tức là cấp phát cho chính vùng nhớ của con trỏ truyền vào. Thế nên ra khỏi hàm con trỏ truyền vào có giá trị (tức là vùng nhớ mới đc cấp phát).

            Comment


            • #7
              Originally posted by 11520327 View Post
              vậy 2 hàm anh đưa ra giải thích sao đây?
              Đơn giản chỉ là con trỏ trỏ đến con trỏ. Thông thường khi bạn muốn thay đổi giá trị của một biến nào đó thông qua một hàm thì bạn truyền địa chỉ của biến đó vào danh sách đối số của hàm, giờ bạn muốn thay đổi con trỏ thì truyền địa chỉ của con trỏ đó vào

              Comment


              • #8
                khi bạn muốn thay đổi giá trị của một biến nào đó thông qua một hàm thì bạn truyền địa chỉ của biến đó vào danh sách đối số của hàm
                a giải thích rõ hơn được không?

                Comment


                • #9
                  Originally posted by 11520327 View Post
                  phần tiếp theo của bài viết " con trỏ trong C".
                  đoạn code:
                  PHP Code:
                  #include<stdio.h>
                  #include<conio.h>

                  void Tag(int *a)
                  {
                      
                  a=new int();
                  };
                  int main()
                  {
                      
                  int *p=NULL;
                      
                  Tag(p);
                      *
                  p=6;

                      
                  printf("%d", *p);
                      
                  getch();
                      return 
                  0;

                  hỏi: khi chạy chương trình thì kết quả như thế nào, giải thích tại sao có kết quả như vậy và đưa ra giải pháp nếu có.
                  xin các bạn lưu ý là mình chỉ thảo luận về con trỏ, những nội dung khác không liên quan đến phần này, xin viết ở topic khác.
                  nè bạn! tiêu đề nói là con trỏ trong C mà sao hàm cấp bộ nhớ động lại của C++ thế, lập trình kiểu này thì văng hết!
                  Tôi không hối tiếc những gì mình đã làm. Tôi chỉ hối tiếc những gì đã không làm khi có cơ hội!

                  Comment


                  • #10
                    Originally posted by 10520191 View Post
                    Code đầu:
                    void Tag(int *a)
                    {
                    a=new int();
                    };
                    -> cấp phát như vậy tức là cấp phát cho biến con trỏ cục bộ (chứ ko phải cấp phát cho biến truyền vào), ra khỏi hàm biến con trỏ cục bộ bị hủy. Thế nên biến truyền vào chưa đc cấp phát :happy:
                    Code sau: cấp phát như mình, tức là cấp phát cho chính vùng nhớ của con trỏ truyền vào. Thế nên ra khỏi hàm con trỏ truyền vào có giá trị (tức là vùng nhớ mới đc cấp phát).
                    Code mà thớt đưa ra thì đúng là lỗi thật.Vì
                    void Tag(int *a)
                    {
                    a=new int();
                    };
                    --> CON trỏ a sẽ đc truyền = tham trị nên khi
                    int *p=NULL;
                    Tag(p);
                    *p=6;
                    -> giá trị trong con trỏ p sẽ đc sao chép sang vùng nhớ mới , sau đó vùng nhớ mới này sẽ đc truyền vào hàm Tag , do đó tag chỉ tác động đến bản sao của p
                    Vậy là khi *p=6 sẽ bị lỗi , vì ta chưa cấp phát bộ nhớ cho p.

                    -Còn riêng đoạn này:
                    Originally posted by 10520191 View Post
                    Code đầu:
                    void Tag(int *a)
                    {
                    a=new int();
                    };
                    -> cấp phát như vậy tức là cấp phát cho biến con trỏ cục bộ (chứ ko phải cấp phát cho biến truyền vào), ra khỏi hàm biến con trỏ cục bộ bị hủy. Thế nên biến truyền vào chưa đc cấp phát \
                    --> Có không bị hủy em nha , nó vẫn tồn tại đấy--> cái này gọi là memory leak

                    Im a british accent lover

                    Comment


                    • #11
                      ra khỏi hàm biến con trỏ cục bộ bị hủy
                      Có không bị hủy em nha , nó vẫn tồn tại đấy--> cái này gọi là memory leak
                      2 ý trên có chút hiểu nhầm. biến cục bộ bị hủy, vùng nhớ cấp phát cho biến cục bộ không bị hủy.
                      khi chạy chương trình thì kết quả như thế nào, giải thích tại sao có kết quả như vậy và đưa ra giải pháp nếu có.
                      code em đưa ra là sai, thế nên phần yêu cầu mới có cái "giải pháp".
                      Last edited by 11520327; 04-10-2012, 23:41.

                      Comment


                      • #12
                        tiêu đề nói là con trỏ trong C mà sao hàm cấp bộ nhớ động lại của C++ thế, lập trình kiểu này thì văng hết!
                        cảm ơn bạn đã nhắc nhở, chỗ này do mình không để ý.

                        Comment


                        • #13
                          Originally posted by 11520327 View Post
                          a giải thích rõ hơn được không?
                          Giải pháp thì chắc mọi người nói rồi ha, nếu cần thì mình sẽ viết lại là
                          Code:
                          void Tag(int **a) 
                          { 
                              (*a) = (int*) malloc(sizeof(int));
                          };
                          OK, còn giải thích, ngắn gọn là vầy

                          Trong C, chỉ có 1 cách truyền tham số, gọi là truyền giá trị. Giá trị của biến được truyền sẽ bị mất sau khi ra khỏi hàm.
                          int* a là kiểu con trỏ, kiểu giá trị là int *, cho nên kiểu giá trị int * sẽ bị mất sau khi ra khỏi hàm tag.
                          Trong C, không phải cứ truyền con trỏ, là giá trị của nó sẽ thay đổi sau khi ra khỏi hàm

                          Còn dài dòng hơn tí thì
                          1 ví dụ dễ hiểu là so sánh việc truyền
                          Code:
                          void tag1(int a)
                          {
                              a = 5;
                          }
                          
                          void tag2(int *a)
                          {
                              *a = null;
                          }
                          
                          int main()
                          {
                              int a = 7;
                              int *x = &a;
                              tag1(a);
                              tag2(b);
                          }
                          Dài dòng hơn nữa thì
                          Bạn muốn đổi giá trị của 1 biến nào đó trong C, thì bạn phải truyền con trỏ cấp cao hơn kiểu con trỏ mà bạn dùng ít nhất là 1 bậc, vì trong C luôn luôn truyền giá trị, nếu bạn truyền con trỏ có cùng cấp thì nó sẽ bị mất do nó ko thể lưu giá trị đó được.
                          Last edited by 09520019; 05-10-2012, 01:03.
                          Khoảng cách giữa bạn và ước mơ của bạn là bao xa ?

                          Comment


                          • #14
                            Originally posted by 09520019 View Post
                            Trong C, chỉ có 1 cách truyền tham số, gọi là truyền giá trị. Giá trị của biến được truyền sẽ bị mất sau khi ra khỏi hàm..
                            câu này của a khó hiểu quá. biến được truyền là biến gì?
                            Theo cách truyền bằng tham trị thì giá trị của biến dùng làm đối số cho hàm sẽ không bị thay đổi.

                            Comment


                            • #15
                              Originally posted by 11520327 View Post
                              câu này của a khó hiểu quá. biến được truyền là biến gì?
                              Theo cách truyền bằng tham trị thì giá trị của biến dùng làm đối số cho hàm sẽ không bị thay đổi.
                              sau khi truyền hàm abc(x) thì x vào trong hàm có thể thay đổi, nhưng ra bên ngoài hàm thì x có giá trị như trước khi nó được truyền

                              Còn 1 ý để ám chỉ là cách 2 bạn này là sai

                              Originally posted by 10520191 View Post
                              ......
                              void Tag(int* &a)
                              {
                              a = new int();
                              }
                              Vì trong C không có kiểu truyền &, mà kiểu truyền & (vd int abc(int &x)) là kiểu truyền của C++, gọi là truyền tham chiếu
                              Khoảng cách giữa bạn và ước mơ của bạn là bao xa ?

                              Comment

                              LHQC

                              Collapse
                              Working...
                              X