Announcement

Collapse
No announcement yet.

Giúp em sáng tỏ 2 vấn đề này với! (chuỗi trong C)

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

  • [C++] Giúp em sáng tỏ 2 vấn đề này với! (chuỗi trong C)

    void main()
    {
    char *p="Bui Tan Quang" khác hoàn toàn với char p[]="Bui Tan Quang";

    p++; Sai nếu khai báo là char p[];

    *p++; <<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    p[2]='b';<<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    }
    Tại sao lại khác biệt như thế trong khi giáo trình viết là *p <=> p[] vậy ạ?
    Last edited by BiThuDoan; 04-12-2011, 20:55.

  • #2
    Originally posted by lytieulong_269 View Post
    void main()
    {
    char *p="Bui Tan Quang" khác hoàn toàn với char p[]="Bui Tan Quang";

    p++; Sai nếu khai báo là char p[];

    *p++; <<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    p[2]='b';<<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    }
    Tại sao lại khác biệt như thế trong khi giáo trình viết là *p <=> p[] vậy ạ?
    Chuỗi "Bui Tan Quang" ở trên được lưu tại vùng rdata session ( vùng nhớ const - chỉ có thể đọc ,không thể thay đổi giá trị tại vùng nhớ đó)
    char *p="Bui Tan Quang"; ->p đơn giản chỉ trỏ tới vùng rdata này mà thôi, p là con trỏ ,p++ bình thường
    Nhưng : char p[]="Bui Tan Quang"; thì lúc này p cũng là 1 con trỏ, nhưng bản thân nó là hằng, nên không thể trỏ tới chỗ khác ( mà việc làm p++ , thì bạn đã cố tình muốn nó trỏ chỗ khác , nên lỗi)

    Tiếp :
    *p++; <<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    p[2]='b';<<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
    thì như mình đã nói hiện tại p đang trỏ tới 1 vùng nhớ const , nghĩa là bạn không thể thay đổi giá trị vùng nhớ đó ( mà cụ thể là bạn không thể thay đổi gia trị chưa "Bui Tan Quang" ở trên) --> Mà *P++ và p[2]='b'; đã đi ngược điều này.

    Vậy bạn sẽ thắc mặc tại sao: char p[]="Bui Tan Quang"; lại đúng với 2 câu lệnh trên .
    -->như mình nói: "Bui Tan Quang"; lưu tại vùng nhớ const , nhưng lúc char p[]="Bui Tan Quang"; thì p sẽ đc cấp phát trên bộ nhớ stack và sao chép nội dung "Bui Tan Quang"; sang vùng nhớ mới cấp phát đó. Và tất nhiên bạn có thể thay đổi vùng nhớ stack này.

    Im a british accent lover

    Comment


    • #3
      Originally posted by lytieulong_269 View Post
      Tại sao lại khác biệt như thế trong khi giáo trình viết là *p <=> p[] vậy ạ?
      Lời giải thích ngắn gọn là nó không tương đương. Tương đương trong tình huống cụ thể nào đó thôi. Con trỏ có thể được dùng để quản lý mảng nhưng nó khác hoàn toàn với mảng.

      Đến lúc em tập làm quen với việc giáo trình chưa chuẩn xác rồi. Đó là lý do vì sao lên đại học người ta học nhiều giáo trình trong 1 môn chứ không phải ôm 1 quyển sách giáo khoa nguyên cả năm như cấp 3

      Comment


      • #4
        Originally posted by 07520004 View Post
        Lời giải thích ngắn gọn là nó không tương đương. Tương đương trong tình huống cụ thể nào đó thôi. Con trỏ có thể được dùng để quản lý mảng nhưng nó khác hoàn toàn với mảng.

        Đến lúc em tập làm quen với việc giáo trình chưa chuẩn xác rồi. Đó là lý do vì sao lên đại học người ta học nhiều giáo trình trong 1 môn chứ không phải ôm 1 quyển sách giáo khoa nguyên cả năm như cấp 3
        mảng cũng là con trỏ, nhưng lại phân biệt hằng hay không hằng, và lại phân biệt trỏ tới vùng nhớ const hay không const

        Im a british accent lover

        Comment


        • #5
          làm sao để phân biệt được vậy anh? em chưa hiểu lắm!

          Comment


          • #6
            Originally posted by 08520016 View Post
            mảng cũng là con trỏ, nhưng lại phân biệt hằng hay không hằng, và lại phân biệt trỏ tới vùng nhớ const hay không const
            nhưng lại xong rồi tới và lại thì anh thấy nó gần khác hẳn rồi =)). Tốt nhất là ban đầu coi như nó không tương đương sau đó tìm hiểu thêm chi tiết từng cái chứ đọc con trỏ lại cứ liên tưởng về mảng ngay dễ tẩu hỏa lắm.

            Comment


            • #7
              Originally posted by lytieulong_269 View Post
              làm sao để phân biệt được vậy anh? em chưa hiểu lắm!
              đọc lại post 2 á.
              thường thì cái này dựa vào kinh nghiệm và chút kiến thức, làm nhiều sẽ gặp.
              Như hôm nay , bạn đã biết thêm 1 chút.

              Im a british accent lover

              Comment


              • #8
                Anh nói Chuỗi "Bui Tan Quang" ở trên được lưu tại vùng rdata session ( vùng nhớ const - chỉ có thể đọc ,không thể thay đổi giá trị tại vùng nhớ đó). Nếu không thay đổi được thì không có gì có thể thay đổi được nó? Vậy tại sao a[3] = 't' phải chăng trái với điều anh nói rồi phải ko?

                Comment


                • #9
                  char *p, là biến con trỏ kiểu char. Trong trường hợp này giá trị của p chính là địa chỉ của ô nhớ đầu tiên của chuỗi "Bui Tan Quang" (cái này chắc bạn đã biết)

                  p++
                  char *p : Vì là kiểu con trỏ nên câu lên trên là hợp lệ, nó sẽ trỏ tới ô nhớ tiếp theo
                  char p[] : Vì p[] là một mảng nên không có operator ++;

                  Mấy lỗi dưới cũng tương tự.
                  *p++; <<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];
                  p[2]='b';<<<<<<<<<<<<<<<<<<<<<<< báo lỗi tại đây Đúng nếu khai báo là char p[];


                  *p <=> p[] : Bạn có thể thực hiện tất cả các truy vấn với mục đích như nhau, nhưng với những thao tác khác nhau, tương ứng với từng kiểu khai báo. (a <=> b, chứ không phải a=b)

                  Phạm Minh Tâm
                  Phone: 01643-652-922
                  Skype ID: tampham47@live.com

                  Comment


                  • #10
                    Originally posted by lytieulong_269 View Post
                    Anh nói Chuỗi "Bui Tan Quang" ở trên được lưu tại vùng rdata session ( vùng nhớ const - chỉ có thể đọc ,không thể thay đổi giá trị tại vùng nhớ đó). Nếu không thay đổi được thì không có gì có thể thay đổi được nó? Vậy tại sao a[3] = 't' phải chăng trái với điều anh nói rồi phải ko?
                    a khai báo sao?

                    Em đọc ki post 2 là biết, anh trả lời hết các trường hợp cho em ui mà

                    Im a british accent lover

                    Comment


                    • #11
                      Originally posted by 09520434 View Post
                      p++
                      char *p : Vì là kiểu con trỏ nên câu lên trên là hợp lệ, nó sẽ trỏ tới ô nhớ tiếp theo
                      char p[] : Vì p[] là một mảng nên không có operator ++;

                      Sai bản chất.

                      Im a british accent lover

                      Comment


                      • #12
                        Cho e hỏi thêm một chút nha! Làm sao để biết một chuỗi khi khai báo sẽ lưu trên "rdata session" rồi khi khai báo char a[] thì nó chuyển sang "stack" gì đó như anh nói vậy??

                        Comment


                        • #13
                          Originally posted by lytieulong_269 View Post
                          Cho e hỏi thêm một chút nha! Làm sao để biết một chuỗi khi khai báo sẽ lưu trên "rdata session" rồi khi khai báo char a[] thì nó chuyển sang "stack" gì đó như anh nói vậy??
                          thì anh nói rồi. kinh nghiệm,làm nhiều biết nhiều. như ở trên anh nói đó là 1 trường hợp.nó là những kiến thức mà e phải thu thập từ nhiều nguồn.

                          giá trị dữ liệu tĩnh sẽ đc lưu ở rdata session:
                          vd: char *a="noi dung1"; int b=3; thì lúc này "noi dung1" và 3 dc lưu trong rdata session.
                          Nhưng có ạn thắc mắc: tại sao ghi : b=2; vẫn OK. --> Hi, tại do tùy dạng dữ liệu ra sao mà copy theo dạng ấy.
                          Thông thường cơ chế shallow-copy sẽ thực hiện.
                          char *a="noi dung1"; thì chỉ đơn giản là sao chép địa chỉ ( nghĩa là a sẽ trỏ tới địa chỉ "noi dung1" )
                          int b=3; copy giá trị 3 sang 1 vùng nhớ mới , nên b và 3 trong rdata session là 2 vùng nhớ khác.

                          Untitled.jpg
                          Last edited by 08520016; 02-12-2011, 02:59.

                          Im a british accent lover

                          Comment


                          • #14
                            hơ! Em mới sưu tầm được đây "Nguyên nhân sâu xa của vấn đề như sau :
                            khi khai báo char *xau="langman-congdongcviet"; thì bản chất là
                            + trong vùng nhớ data của chương trình sẽ có 1 hằng chuỗi "langman-congdongcviet" . <<<< là hằng chuỗi, đã là hằng thì ko thể bị thay đổi
                            + cho con trỏ xau trỏ đến đầu của vùng nhớ đó.
                            Câu lệnh tiếp theo xau[6]='A'; cố tình thay đổi giá trị của hằng , rõ ràng là sinh ra lỗi rồi!"

                            Comment


                            • #15
                              Originally posted by lytieulong_269 View Post
                              hơ! Em mới sưu tầm được đây "Nguyên nhân sâu xa của vấn đề như sau :
                              khi khai báo char *xau="langman-congdongcviet"; thì bản chất là
                              + trong vùng nhớ data của chương trình sẽ có 1 hằng chuỗi "langman-congdongcviet" . <<<< là hằng chuỗi, đã là hằng thì ko thể bị thay đổi
                              + cho con trỏ xau trỏ đến đầu của vùng nhớ đó.
                              Câu lệnh tiếp theo xau[6]='A'; cố tình thay đổi giá trị của hằng , rõ ràng là sinh ra lỗi rồi!"
                              ở post 2 anh đã nói rồi cơ mà

                              Im a british accent lover

                              Comment

                              LHQC

                              Collapse
                              Working...
                              X