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ố 14 kết quả

Đề tài: Cảnh báo "deprecated conversion from string constant to 'char*'" và hướng giải quyết

  1. #1
    Ngày gia nhập
    08 2011
    Nơi ở
    /pentest
    Bài viết
    44

    Mặc định Cảnh báo "deprecated conversion from string constant to 'char*'" và hướng giải quyết

    Mình đang đọc cuốn C++ của thầy Phạm Văn Ất tại http://diendan.congdongcviet.com/showthread.php?t=1093(cám ơn thầy đã viết ra một tài liệu rất hay): có một đoạn code mình muốn các bạn cùng thảo luận về đoạn code này xem có vấn đề gì và cách giải quyết để mọi người cùng tránh. Thân.

    C++ Code:
    1. #include<iostream.h>
    2. #include<conio.h>
    3. void ht(char *dc="HANOI",int n=10);
    4. void ht(char *dc,int n)
    5.     {
    6.       for(int i=1;i<=n;i++)
    7.         Cout<<"\n\n"<<dc;
    8.     }
    9. void main()
    10.    {
    11.      ht();
    12.      ht("abc",3);
    13.      ht("def");
    14.      getch();
    15.   }
    Đã được chỉnh sửa lần cuối bởi meterpreter : 30-09-2011 lúc 05:59 AM. Lý do: chỉnh sửa cho phù hợp. vì nhầm lẫn một chút + xóa bớt getch();clrscr();

  2. #2
    Ngày gia nhập
    04 2008
    Nơi ở
    Bốn bề là nhà
    Bài viết
    697

    C++ Code:
    1. void ht(char dc[]="HANOI",int n=10);

  3. #3
    Ngày gia nhập
    08 2011
    Nơi ở
    /pentest
    Bài viết
    44

    Trích dẫn Nguyên bản được gửi bởi G.Perelman Xem bài viết
    C++ Code:
    1. void ht(char dc[]="HANOI",int n=10);
    Cách này hoàn toàn được, vẫn còn một cách khác, bạn có thể cắt nghĩa tại sao bạn lại có khai báo như trên ko?

  4. #4
    Ngày gia nhập
    01 2011
    Nơi ở
    -Mountain-
    Bài viết
    768

    C++ Code:
    1. #include<iostream>
    2. #include<conio.h>
    3. using namespace std;
    4. void ht(const char *dc="HANOI",int n=10); //
    5. void ht(const char *dc,int n) //
    6.     {
    7.       for(int i=1;i<=n;i++)
    8.         cout<<"\n\n"<<dc;
    9.     }
    10. int main()
    11.    {
    12.      ht();
    13.      getch();
    14.      //clrscr();
    15.      ht("abc",3);getch();//clrscr();
    16.      ht("def");
    17.      return 0;
    18.      getch();
    19.   }
    Lỗi này đơn giản thôi. Đây là lỗi khi chuyển đổi từ hằng xâu sang xâu
    ps nhỏ: Một số trình biên dịch có thể chấp nhận đc lỗi này

  5. #5
    Ngày gia nhập
    08 2011
    Nơi ở
    /pentest
    Bài viết
    44

    Perfect như vậy có 2 cách khắc phục đó là:

    1:
    C Code:
    1.   char dc[] = "HANOI";

    2:
    C Code:
    1.   const char *dc = "HANOI";

    Trong C sẽ không có cảnh báo cho lỗi này, C++ thì có cảnh báo chỉ vì nó phân biệt char * với const char* là hai kiểu dữ liệu phân biệt. Chuẩn C++ không hỗ trợ cho việc chuyển đổi từ một kiểu hằng sang một kiểu không phải là hằng, "HANOI" là một hằng chuỗi vì nó được bao bọc bởi dấu ngoặc kép và kiểu của nó là const char* do vậy nó khác với kiểu char *. Để minh họa mình lấy ví dụ sau.

    C Code:
    1. const int y = 8;           // y là hằng và không thể bị sửa đổi
    2. const int* pY = &y;        // bạn không thể sửa đổi y thông qua pY
    3.  
    4. cout << y << endl;         // in ra số 8
    5.  
    6. int* pY2 = (int *)pY;      // ép kiểu tường minh pY có kiểu int *
    7. *pY2 = 7;                  // kết quả là undefined
    8. cout << y << endl;        // giá trị của y in ra là bao nhiêu?

    Trên máy của mình chuơng trình vẫn chạy nhưng cả 2 lần in ra y đều có kết quả là 8.

  6. #6
    Ngày gia nhập
    01 2011
    Nơi ở
    -Mountain-
    Bài viết
    768

    Mặc định Cảnh báo "deprecated conversion from string constant to 'char*'" và hướng giải quyết

    Trích dẫn Nguyên bản được gửi bởi meterpreter Xem bài viết
    Perfect như vậy có 2 cách khắc phục đó là:

    1:
    C Code:
    1.   char dc[] = "HANOI";

    2:
    C Code:
    1.   const char *dc = "HANOI";

    Trong C sẽ không có cảnh báo cho lỗi này, C++ thì có cảnh báo chỉ vì nó phân biệt char * với const char* là hai kiểu dữ liệu phân biệt. Chuẩn C++ không hỗ trợ cho việc chuyển đổi từ một kiểu hằng sang một kiểu không phải là hằng, "HANOI" là một hằng chuỗi vì nó được bao bọc bởi dấu ngoặc kép và kiểu của nó là const char* do vậy nó khác với kiểu char *. Để minh họa mình lấy ví dụ sau.

    C Code:
    1. const int y = 8;           // y là hằng và không thể bị sửa đổi
    2. const int* pY = &y;        // bạn không thể sửa đổi y thông qua pY
    3.  
    4. cout << y << endl;         // in ra số 8
    5.  
    6. int* pY2 = (int *)pY;      // ép kiểu tường minh pY có kiểu int *
    7. *pY2 = 7;                  // kết quả là undefined
    8. cout << y << endl;        // giá trị của y in ra là bao nhiêu?

    Trên máy của mình chuơng trình vẫn chạy nhưng cả 2 lần in ra y đều có kết quả là 8.
    Mặc dù mình thấy cái ví dụ của bạn ko liên quan tới bài viết lắm
    Nhưng vẫn muốn hỏi bạn về đoạn code này

    const int y = 8; // y là hằng và không thể bị sửa đổi
    const int* pY = &y; // bạn không thể sửa đổi y thông qua pY

    cout << y << endl; // in ra số 8

    int* pY2 = (int *)pY; // ép kiểu tường minh pY có kiểu int *
    *pY2 = 7; // kết quả là undefined
    cout << y << endl; // giá trị của y in ra là bao nhiêu?
    Nếu như cout << *pY2 thì k quả = ? Giải thích tại sao lại ko = 8
    còn kết quả y = 8 thì bạn cứ in thế nào thì y cũng bằng 8 thôi nên đừng thắc mắc

  7. #7
    Ngày gia nhập
    08 2011
    Nơi ở
    /pentest
    Bài viết
    44

    Mình lướt rất nhiều tô píc trong 4frum, có rất nhiều tranh cãi về vấn đề char s[] hay char *s khác nhau giống nhau thế nào. Code trên mình minh họa cho việc cố tình thay đổi một vùng nhớ đã được khai báo là hằng, sự thay đổi đó dẫn tới hậu quả là vẫn ko thay đổi được nó (trên OS của mình thôi) còn cái gán *pY2 = 7; nó ko được chuẩn C++ định nghĩa do đó kết quả trả về là không đoán trước được (bạn mất quyền kiểm soát kết quả trả về). Tại sao mình lấy ví dụ như vậy để mọi người hiểu rằng const char * và char * là hoàn toàn khác nhau và nếu không may bạn gán một biến chứa dữ liệu kiểu const char * vào biến chứa dữ liệu kiểu char * thì hậu quả là khôn lường(vì rất có khả năng bạn dùng biến kiểu char * để thay đổi biến kiểu const char *). Chỉ thế thôi. Hi vọng điều này giải thích hợp lý cho nụ cười của bạn.

    SR lần nữa vì có một sự nhầm lẫn khi tạo nên topic này. Nhưng giờ thì có vẻ cũng ổn.
    Đã được chỉnh sửa lần cuối bởi meterpreter : 28-09-2011 lúc 02:17 AM. Lý do: chỉnh sửa cho hợp lý

  8. #8
    Ngày gia nhập
    01 2011
    Nơi ở
    -Mountain-
    Bài viết
    768

    *pY2 = 7; Mình in ra vẫn thế thôi . Tại sao lại mất quyền kiểm soát ?
    Còn cái mình hỏi là cái in ra y ? Đương nhiên = 8. Mình thấy thắc mắc khi bạn đặt dấu ? ở đó

    Còn chuyện const char* và char* là hoàn toàn khác nhau đâu có gì để bàn cãi

  9. #9
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Đọc thì char * hay const char * đều như nhau cả thôi. Nhưng đến khi ghi thì mới có chuyện. Đây là 1 trường hợp điển hình xảy ra khi biên dịch trên win với trình biên dịch vc.
    C Code:
    1. char *s = "HANOI";
    2. s[0] = 'h';

    "HANOI" là kiểu const char *. Đoạn code đã cố gắng ép qua char * và gán vào cho s. Hậu quả thì bạn cứ chạy thử sẽ rõ.

    Trong mô hình bộ nhớ của đa số các chương trình trong win, bộ nhớ của chương trình được chia ra làm nhiều section. Mỗi section sẽ được phân quyền khác nhau. Có 3 quyền cơ bản là chỉ đọc, đọc/ghi, thực thi. Ở đây chuỗi "HANOI" được đặt trong vùng nhớ có quyền chỉ được đọc. Do đó bạn đọc thông qua biến s thì ko có vấn đề gì. Nhưng nếu bạn ghi thì bạn ko có quyền và chương trình sẽ crash khi cố thực hiện việc đó. Chính vì nguyên nhân này, trình biên dịch phải cảnh báo cho bạn biết khả năng sẽ có lỗi nếu như cố ép từ const char * sang char *. Đây chỉ là cảnh báo, vì nếu bạn ép kiểu nhưng chỉ thực hiện việc đọc nội dung vùng nhớ thì chương trình sẽ vẫn bình an vô sự.
    Đã được chỉnh sửa lần cuối bởi meoconlongvang : 28-09-2011 lúc 11:19 AM.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  10. #10
    Ngày gia nhập
    08 2011
    Nơi ở
    /pentest
    Bài viết
    44

    const int y = 8;
    const int* pY = &y;

    int* pY2 = (int *)pY;

    Bạn ơi mình đã ép kiểu tường minh cho pY từ kiểu const int * thành kiểu int *, mà khi định nghĩa pY mình đã cho nó nắm địa chỉ của y vì pY ban đầu được khai báo là const int * nên giá trị mà pY nắm giữ (y) không thể bị thay đổi bởi pY. Nếu cố tình thay đổi thì bạn sẽ ko thay đổi được (tức kết quả ngoài sự mong đợi) không chỉ dừng ở đó kết quả là ko thể đoán biết trước, mình nói là hệ thống của mình cho kết quả là 8 nhưng qua hệ thống khác thì ko biết được, nó có thể là 10, 100 etc.

    @mèo: hệ thống ko crash bạn àh, tớ vẫn compile và run mà ko bị crash mặc dù tớ cố gắng ghi (thay đổi y) thông qua pY với việc ép kiểu pY.
    Đã được chỉnh sửa lần cuối bởi meterpreter : 28-09-2011 lúc 11:26 AM.

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

  1. Trả lời: 5
    Bài viết cuối: 22-11-2012, 11:05 AM
  2. Code C bị lỗi "unterminated string or character constant"
    Gửi bởi D.Max trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 0
    Bài viết cuối: 21-03-2012, 06:50 PM
  3. Mã nguồn C Lỗi Lỗi "syntax error before numeric constant" trong code sắp xếp chuỗi mảng 2 chiều?
    Gửi bởi levandan trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 4
    Bài viết cuối: 15-04-2011, 11:43 PM
  4. Kỹ thuật C++ 'char' và "string" khác nhau như thế nào?
    Gửi bởi kenium trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 6
    Bài viết cuối: 18-11-2010, 09:03 PM
  5. Đề xuất Thêm flag "Đã giải quyết" (Resolved) hay "chưa giải quyết" cho topic
    Gửi bởi cuonchagio trong diễn đàn Ý kiến, đề xuất và khiếu nại
    Trả lời: 3
    Bài viết cuối: 28-01-2010, 05:34 PM

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