Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 8 của 8
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Gặp vấn đề về truy xuất con trỏ trong struct và union

    Chào các bạn,

    Mình đang gặp vấn đề về con trỏ trong struct và union, nhờ các bạn giúp đỡ. Mình có khai báo và 2 hàm sau, mình post code chạy đúng trước:

    Khai báo:
    Mã:
    typedef union TextLCDDataPort_Union
    {
      unsigned char BYTE;
      struct
      {
        unsigned char B0 : 1;
        unsigned char B1 : 1;
        unsigned char B2 : 1;
        unsigned char B3 : 1;
        unsigned char B4 : 1;
        unsigned char B5 : 1;
        unsigned char B6 : 1;
        unsigned char B7 : 1;
      }BIT;
    }TextLCDDataPort_TypeDef;
    
    TextLCDDataPort_TypeDef DataTextLCD;
    Các hàm sử dụng khai báo trên:

    Mã:
    void TextLCD_PortTextLCDWrite()
    {
      TextLCD_D4 = DataTextLCD.BIT.B4;
      TextLCD_D5 = DataTextLCD.BIT.B5;
      TextLCD_D6 = DataTextLCD.BIT.B6;
      TextLCD_D7 = DataTextLCD.BIT.B7;
    }
    Mã:
    void TextLCD_Cmd(char cmd_data)
    {
      unsigned char HighNibble, LowNibble;
      
      HighNibble = (cmd_data) & 0xF0;
      LowNibble = (cmd_data<<4) & 0xF0;
      
      DataTextLCD.BYTE = HighNibble;
      TextLCD_PortTextLCDWrite();
      ...
      
      DataTextLCD.BYTE = LowNibble;
      TextLCD_PortTextLCDWrite();
      ...
    }
    Bây giờ mình đổi khai báo lại thành con trỏ hết:
    Mã:
    typedef union TextLCDDataPort_Union
    {
      unsigned char *BYTE;
      struct
      {
        unsigned char B0 : 1;
        unsigned char B1 : 1;
        unsigned char B2 : 1;
        unsigned char B3 : 1;
        unsigned char B4 : 1;
        unsigned char B5 : 1;
        unsigned char B6 : 1;
        unsigned char B7 : 1;
      }*BIT;
    }TextLCDDataPort_TypeDef;
    
    TextLCDDataPort_TypeDef *DataTextLCD;
    Các hàm cũng sửa lại cho phù hợp:
    Mã:
    void TextLCD_PortTextLCDWrite()
    {
      TextLCD_D4 = DataTextLCD->BIT->B4;
      TextLCD_D5 = DataTextLCD->BIT->B5;
      TextLCD_D6 = DataTextLCD->BIT->B6;
      TextLCD_D7 = DataTextLCD->BIT->B7;
    }
    Mã:
    void TextLCD_Cmd(char cmd_data)
    {
      unsigned char HighNibble, LowNibble;
      
      HighNibble = (cmd_data) & 0xF0;
      LowNibble = (cmd_data<<4) & 0xF0;
      
      *DataTextLCD->BYTE = HighNibble;
      TextLCD_PortTextLCDWrite();
      ...
    
      *DataTextLCD->BYTE = LowNibble;
      TextLCD_PortTextLCDWrite();
      ...
    }
    Sửa lại như thế, biên dịch thì được, nhưng chạy trên phần cứng thì không đúng. Các bạn cho mình hỏi mình sửa lại như thế thì sai ở chỗ nào? Sửa sao lại cho đúng? Cám ơn các bạn!

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bạn thử thêm dấu () trong: *DataTextLCD->BYTE = HighNibble; xem.

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    *(DataTextLCD->BYTE)


    à ko phải, operator -> ưu tiên hơn * nên viết *DataTextLCD->BYTE vẫn đúng.

    chỗ sai là BIT và BYTE là CON TRỎ, nên khai báo
    TextLCDDataPort_TypeDef *DataTextLCD;

    thì BIT và BYTE ko biết trỏ tới đâu => khi deref nó sẽ gây ra lỗi. Hơn nữa DataTextLCD cũng chưa được cấp phát bộ nhớ nên khi gọi ->BYTE là đã gây ra lỗi rồi.

    phải malloc cho DataTextLCD, rồi malloc cho DataTextLCD->BIT và malloc cho DataTextLCD->BYTE

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Chưa hiểu ý malloc của bạn lắm! Như vậy khi mallloc của 3 thằng đó thì code chạy được?
    Do bạn vẫn chưa cấp phát vùng nhớ cho BIT hoặc BYTE nên khi bạn viết *DataTextLCD->BYTE = HighNibble; nó ghi dữ liệu vào nơi mà nó không nên ghi --> lỗi.


    Thêm nữa là mình có nghe một khái niệm con trỏ trỏ tới con trỏ. Ở trong trường hợp *DataTextLCD trỏ tới *BYTE thì không phải là con trỏ trỏ đến con trỏ sao?
    DataTextLCD là biến con trỏ kiểu cấu trúc chứa dữ liệu BYTE - kiểu con trỏ nên không phải là con trỏ trỏ đến con trỏ.

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mã:
    typedef union TextLCDDataPort_Union
    {
      unsigned char *BYTE;
      struct
      {
        unsigned char B0 : 1;
        unsigned char B1 : 1;
        unsigned char B2 : 1;
        unsigned char B3 : 1;
        unsigned char B4 : 1;
        unsigned char B5 : 1;
        unsigned char B6 : 1;
        unsigned char B7 : 1;
      }BIT;
    }TextLCDDataPort_TypeDef;
    
    TextLCDDataPort_TypeDef DataTextLCD;
    kiểu này vẫn ko đúng. BIT là 1 byte chứa 8 bit, còn BYTE là con trỏ có thể là 16-bit 32-bit hay 64-bit. BIT chứa dữ liệu còn BYTE là con trỏ, chứa địa chỉ. Địa chỉ khác dữ liệu [IMG]images/smilies/17.gif[/IMG]

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cảm ơn mấy bạn nhiều lắm! Mình học điện tử, có dùng C để lập trình, nên kiến thức chưa sâu, có gì mong các bạn giúp đỡ thêm!

    Đúng là khi mình khai báo như thế này thì chạy được:

    Mã:
    typedef union TextLCDDataPort_Union
    {
      unsigned char *BYTE;
      struct
      {
        unsigned char B0 : 1;
        unsigned char B1 : 1;
        unsigned char B2 : 1;
        unsigned char B3 : 1;
        unsigned char B4 : 1;
        unsigned char B5 : 1;
        unsigned char B6 : 1;
        unsigned char B7 : 1;
      }BIT;
    }TextLCDDataPort_TypeDef;
    
    TextLCDDataPort_TypeDef DataTextLCD;
    Chưa hiểu ý malloc của bạn lắm! Như vậy khi mallloc của 3 thằng đó thì code chạy được?

    Thêm nữa là mình có nghe một khái niệm con trỏ trỏ tới con trỏ. Ở trong trường hợp *DataTextLCD trỏ tới *BYTE thì không phải là con trỏ trỏ đến con trỏ sao?

    - - - Nội dung đã được cập nhật ngày 18-12-2015 lúc 11:30 AM - - -

    Trích dẫn Gửi bởi greigaz
    viết như vậy thì 2 con trỏ BIT với BYTE cùng trỏ về 1 địa chỉ rồi, cho nên chỉ cần cho 1 thằng thôi.
    Mình nghĩ BYTE và BIT cùng 1 vùng nhớ khi dùng union, thì trỏ về cùng 1 địa chỉ là đúng rồi chứ?

  7. #7
    Trích dẫn Gửi bởi INTP
    *(DataTextLCD->BYTE)


    à ko phải, operator -> ưu tiên hơn * nên viết *DataTextLCD->BYTE vẫn đúng.

    chỗ sai là BIT và BYTE là CON TRỎ, nên khai báo
    TextLCDDataPort_TypeDef *DataTextLCD;

    thì BIT và BYTE ko biết trỏ tới đâu => khi deref nó sẽ gây ra lỗi. Hơn nữa DataTextLCD cũng chưa được cấp phát bộ nhớ nên khi gọi ->BYTE là đã gây ra lỗi rồi.

    phải malloc cho DataTextLCD, rồi malloc cho DataTextLCD->BIT và malloc cho DataTextLCD->BYTE
    viết như vậy thì 2 con trỏ BIT với BYTE cùng trỏ về 1 địa chỉ rồi, cho nên chỉ cần cho 1 thằng thôi.

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    ồ ta ko để ý cái DataTextLCD là union, vậy thì chỉ cấp phát cho BYTE hoặc BIT thôi

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •