Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 15 kết quả

Đề tài: tên mảng bên Stack là con trỏ hằng

  1. #1
    Ngày gia nhập
    03 2008
    Bài viết
    9

    Mặc định tên mảng bên Stack là con trỏ hằng

    int a[5]= {0, 1, 2, 3, 4}; //kích thước của mảng là 20 byte, mỗi phần tử 4 byte (kích thước kiểu int)
    int* pa= a; //kích thước của pa và a là 4 byte (kích thước con trỏ)

    &pa và a là 2 địa chỉ bộ nhớ khác nhau trong Stack, a là con trỏ hằng chứa địa chỉ là byte đầu tiên của vùng nhớ được cấp phát cho mảng (hay nói là a trỏ tới mảng), pa cũng là con trỏ (không hằng) và cũng chứa địa chỉ mà a đang chứa. pa và a là 2 con trỏ nên có kích thước là 4 byte (trên máy mình).
    phần hỏi đây:
    a và &a[0] là cùng 1 địa chỉ, vậy 4 byte của a[0] dùng để chứa dữ liệu (tức là số 0 như khởi tạo cho a[0]) hay 4 byte này chứa địa chỉ của byte đầu tiên thuộc mảng (tức là 4 byte này sẽ dành cho con trỏ a dùng chứa địa chỉ đối tượng mà a trỏ tới). Ai cũng biết trường hợp đầu là đúng.
    vậy 4 byte dùng cho con trỏ a ở đâu? (trình biên dịch cũng phải cấp cho con trỏ a 4 byte bộ nhớ đúng không nè). Mình kiểm tra thấy nó cũng là 4 byte mà trình biên dịch đã cấp cho a[0] ===> mâu thuẫn ở 4 byte này
    Bạn nào giải quyết mâu thuẫn này dùm nha.

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    pa và a là 2 con trỏ nên có kích thước là 4 byte (trên máy mình).
    Cậu làm cách nào in ra a 4 byte thử xem ? a là con trỏ hằng đến phần tử đầu tiên đồng thời a cũng là tên mãng -> nó không phải con trỏ bình thường. Chẳng có mâu thuẫn gì hết, đọc lại lý thuyết kĩ 1 chút sẽ hiểu :
    C++ Code:
    1. #include <iostream>
    2.  
    3. int main()
    4. {
    5.   int arrD[3] = {1,2,3};
    6.   int *ptr = arrD;
    7.   std::cout << sizeof(ptr) << '\n';
    8.   std::cout << sizeof(arrD) << '\n';
    9.  
    10.   return 0;
    11. }

  3. #3
    Ngày gia nhập
    02 2008
    Bài viết
    88

    Mới học vài ngày góp vui
    Code:
    int a[5]= {0, 1, 2, 3, 4};
    int* pa= a;
    Kết quả
    Code:
    pa=a=&a[0];
    *pa=a[0];
    Đã được chỉnh sửa lần cuối bởi anhtuyenbk : 20-03-2008 lúc 08:01 AM.
    Mình từ Caulacbovb qua)
    Giã từ VB6 đến với VB.Net, C# và Java.

  4. #4
    Ngày gia nhập
    03 2008
    Bài viết
    9

    Gặp lại rox_rook nữa và lần này cậu cũng chưa hiểu ý mình. Sao khả năng bài tỏ của mình tệ quá, con trai mà còn không hiểu huống chi là con gái ==> chắc mình cô đơn tới già quá, huhu.
    a là con trỏ hằng chứa địa chỉ là byte đầu tiên của vùng nhớ được cấp phát cho mảng (hay nói là a trỏ tới mảng) => cậu nói là a là con trỏ hằng trỏ tới phần tử đầu của mảng ==> cũng giống nhau thôi ===> ok chổ này nha.
    con trỏ sẽ được trình biên dịch cấp 2 hay 4 byte tùy theo hệ thống (máy mình là 4 byte). pa là con trỏ nên sizeof(pa)= 4 byte. ==> a cũng là con trỏ (con trỏ hằng) nên có size là 4 byte ===> ok đi rồi giải thích sau.
    a là con trỏ hằng đến phần tử đầu tiên đồng thời a cũng là tên mãng -> nó không phải con trỏ bình thường (câu của cậu đó)
    => sizeof(a)= size của mảng, lúc này a đóng vai trò là biến mảng không phải con trỏ nữa, vì nếu là con trỏ thì sẽ cho ra 4 byte chứ không phải size của mảng ===> không có cách nào để kiểm tra a là 4 byte (với kiến thức hiện giờ của mình), mình khẳng định con trỏ a là 4 byte là suy luận từ pa thôi (các con trỏ đều 4 byte mà).
    Rồi xong. Mâu thuẫn là ở chổ này đây
    int* pa= a;
    cout<< a<< " - "<< pa;//cùng giá trị địa chỉ
    cout<< &a<< " - "<< &pa;//khác giá trị địa chỉ
    trong 2 dòng cout trên, a đóng vai trò là con trỏ (không phải là biến mảng như trên nữa). Là con trỏ thì phải có vùng nhớ riêng (là 4 byte) để lưu giá trị địa chỉ của đối tượng mà nó trỏ tới.
    Ví dụ pa lưu giá trị địa chỉ 89abcdef (là địa chỉ byte đầu tiên của mảng), và &pa là 12345678 (một giá trị địa chỉ nào đó chắc chắn sẽ khác 89abcdef). Bây giờ ta hãy thay pa bằng a trong ví dụ này đi ==> kết quả là cái mình cho là mâu thuẫn.
    a sẽ lưu giá trị địa chỉ 89abcdef (nội dung con trỏ)
    &a cũng cho giá trị địa chỉ là 89abcdef (địa chỉ con trỏ)
    ==> mẫu thuẫn là a và &a lại giống nhau (so sánh với pa và &pa)

  5. #5
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Check dưới nick của tui, có 1 lần tui đã giải thích rất kĩ về cái này rùi, p là con trỏ tới mãng a nhưng p và a là hoàn toàn khác nhau.
    ==> mẫu thuẫn là a và &a lại giống nhau (so sánh với pa và &pa)
    Omg, đọc kĩ lại lý thuyết của mãng và con trỏ dùm tui đi cậu à.

  6. #6
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Mặc định tên mảng bên Stack là con trỏ hằng

    Ok, ví dụ này, ptr1 và ptr2 bắt buộc phải giống nhau ?
    C++ Code:
    1. #include <iostream>
    2.  
    3. int main(){
    4.   int value = 10;
    5.   int* ptr1 = &value;
    6.   int* ptr2 = &value;
    7.  
    8.   std::cout << ptr1 << '\n';
    9.   std::cout << ptr2 << '\n';
    10.  
    11.   std::cout << long(&ptr1) << '\n';
    12.   std::cout << long(&ptr2) << '\n';
    13.  
    14.   return 0;
    15. }

  7. #7
    Ngày gia nhập
    03 2008
    Bài viết
    9

    không biết phải giải thích sao cho rox_rook hiểu ý mình nữa... bó tay rồi. Khi nào có thời gian xin hãy đọc lại rồi suy nghĩ "sâu" vào nha.
    Khi nào bản thân mình tìm được lời giải sẽ gửi lên.

  8. #8
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Thực ra cái dấu & nó cũng lắm phiền phức, down thư viện boost về lấy hàm này ra mà test cậu sẽ hiểu thấu đáo vấn đề giữa "tên mãng" và con trỏ.
    C++ Code:
    1. #include <iostream>
    2. #include "boost/utility.hpp"
    3.  
    4. int main(){
    5.     int arrD[] = {1,2,3};
    6.     int* pointer_to_arrD = arrD;
    7.     std::cout << boost::addressof(arrD) << '\n';
    8.     std::cout << boost::addressof(pointer_to_arrD) << '\n';
    9.     std::cout << boost::addressof(arrD[0]) << '\n';
    10.      
    11.     return 0;
    12. }
    boost:: là namspace của boost giống std:: của STL vậy, không có gì hết.
    addressof là hàm đặc biệt của header boost utility, muốn lấy address của thằng nào, thì cứ như trên mà làm.
    hông có cách nào để kiểm tra a là 4 byte (với kiến thức hiện giờ của mình), mình khẳng định con trỏ a là 4 byte là suy luận từ pa thôi (các con trỏ đều 4 byte mà).
    Chỗ này là sai, tên mãng không phải con trỏ thường, nó không phải 4 byte.

  9. #9
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    không biết phải giải thích sao cho rox_rook hiểu ý mình nữa... bó tay rồi. Khi nào có thời gian xin hãy đọc lại rồi suy nghĩ "sâu" vào nha.
    Nếu cậu mới học thì tui khuyên cậu, cậu hãy suy nghĩ lại chứ không phải tui, tui từng trãi qua giai đoạn này nên tui hiểu, vấn đề của cậu là không đọc kĩ lý thuyết trước khi suy luận. Tui không dám nói tui giỏi gì, nhưng tui nghĩ kinh nghiệm xài con trỏ và hiểu cấp phát động có lẽ hơn cậu. Một con trỏ đơn thuần và tên mãng ( 1 con trỏ hằng ) là khác nhau, mặc dù nhìn vào thì cứ nghĩ tác vụ của nó là như nhau, nhưng nó không phải vậy.
    Khi nào bản thân mình tìm được lời giải sẽ gửi lên.
    Cái kết quả là đơn giản và dễ hiểu, nếu cậu muốn làm cho phức tạp thì tùy cậu vậy !

  10. #10
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Sorry, lỡ tay nên double post. Cho cậu thêm 1 ví dụ nữa :
    C++ Code:
    1. #include <iostream>
    2.  
    3. int main(){
    4.     char arrD[] = {1,2,3};
    5.     char* pointer_to_arrD = arrD;
    6.     std::cout << sizeof(pointer_to_arrD) << '\n';
    7.     return 0;
    8. }
    Cậu nghĩ xem sizeof con trỏ lúc này có là 1 không ?
    Đã được chỉnh sửa lần cuối bởi rox_rook : 20-03-2008 lúc 11:16 AM.

Các đề tài tương tự

  1. Giúp mình kích danh mục bên trái, nó load url vào khung bên phải
    Gửi bởi jockthree trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 0
    Bài viết cuối: 26-09-2013, 11:50 AM
  2. Cơ sở làm huy hiệu, bảng tên nhân viên, bảng tên mica, bảng tên ăn mòn, bảng tên thay tên
    Gửi bởi tranngocson186 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 25-05-2013, 08:37 AM
  3. Cấu trúc dữ liệu Chuyển các phần tử từ stack này sang stack kia như thế nào?
    Gửi bởi rukawa1184 trong diễn đàn Thắc mắc CTDL & Giải thuật
    Trả lời: 9
    Bài viết cuối: 06-12-2011, 06:52 PM
  4. Code về stack | Chuyển hệ số 10 sang 2 dùng stack
    Gửi bởi ahappyboy89 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 13
    Bài viết cuối: 17-04-2009, 09:48 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn