01/10/2018, 16:25

Char *str = "hello"; không dùng được trên visual studio 2017?

chào các bác, em đang học về lập trình, hôm nay đọc được một số tài liệu thấy ngta khai báo chuỗi kí tự như vậy:

char *str = "hello";
char str[] = "hello";

và khi em đem về dùng thử thì gặp lỗi ở kiểu khai báo đầu tiên, chương trình của em như vầy:


int main()
{
char *str = "hello"; // lỗi ở đây
_getch();
return 0;
}

Bộ trên vs2017 nó không cho dùng kiểu khai báo này sao? Các bác hỗ trợ giúp em với.

Trần Hoàn viết 18:37 ngày 01/10/2018

Bạn chụp hình cho mọi người xem lỗi. Kiểm tra các thư viện được include.

KieuThinh viết 18:29 ngày 01/10/2018

Văn Dương viết 18:34 ngày 01/10/2018

Lỗi báo rõ ràng rồi nhé.
“hello” được nhận dạng là 1 const char* thì nó không gán được cho một char*.

Có thể viết thế này:

KieuThinh viết 18:28 ngày 01/10/2018

Vậy sao bác trên kia lại khai báo được còn của em thì không? Bác nào biết cách sửa không giúp em với?

rogp10 viết 18:40 ngày 01/10/2018

Đúng ra là const char* lí do là vì literal strings không sửa được (segfault) nên không const nó không chịu. Mấy ver sau của VS càng lúc càng nhắng nên thôi dùng IDE khác vậy, nó chỉ có mỗi C# là dùng được.

viết 18:31 ngày 01/10/2018

Sách nào viết là char * s = "hello" thì đốt sách đó đi, đơn giản.

Vì đó là cách viết sai, và cái đơn giản viết còn ko đúng thì mấy cái khó hơn viết chắc còn sai tùm lum nữa, đốt đi là cách tốt nhất. Phải cám ơn trình biên dịch nó cấm viết như vậy mới đúng. Trình dịch nào cho phép thì uninstall nó ngay ~.~

Pham Van Hai viết 18:36 ngày 01/10/2018

Trong C thì nó vẫn hợp lệ chứ nhỉ, C++ thì ko hợp lệ. Tuy nhiên dùng const char *str vẫn tường minh hơn.

stackoverflow.com
peter.slizik

ANSI C: Pointers to strings literals

c, string-literals
asked by peter.slizik on 03:17PM - 23 Nov 11
KieuThinh viết 18:39 ngày 01/10/2018

char *var nghĩa là khai báo con trỏ var thuộc kiểu char. char var[] nghĩa là khai báo mảng var có kiểu char, nếu không gán ngay lúc khai báo thì phải để thêm chỉ số (số lượng phần tử) trong cặp [] nữa. VD: char var[30];. Còn sự khác biệt thì có một vài điểm cần lưu ý như sau: Khi để char *var = "string"; thì đồng nghĩa với việc bạn sẽ cho con trỏ var này trỏ đến một vùng dữ liệu hằng có tên string trong vùng nhớ Constant (vùng nhớ chỉ read-only, mọi thao tác chỉnh sửa, thay đổi, ... sẽ bị vi …

https://daynhauhoc.com/t/khac-biet-giua-khai-bao-mang-char-va-con-tro-char/3600

Em tìm hiểu về con trỏ và chuỗi thì thấy mấy bài này, trong đó thấy họ khai báo như vậy em mới đem về thử thôi mà

name viết 18:27 ngày 01/10/2018

câu hỏi hay có đóng góp lớn về sự cập nhập kiến thức

NBQ viết 18:34 ngày 01/10/2018

Sao lại đốt sách với gỡ trình dịch đi nhỉ? Mình nghĩ người ta có quyền khai báo char* s = “hello” chứ, miễn là người sử dụng hiểu rõ và chú ý không thay đổi nội dung mà con trỏ *s trỏ tới là được chứ. GCC phổ biến như thế vẫn cho phép khai báo đấy thôi, vậy cũng phải gỡ đi ư? Còn Visual Studio của Microsoft taoj ra rule riêng của họ thì mình muốn dùng thì phải tuân thủ thôi.

rogp10 viết 18:32 ngày 01/10/2018

Đúng vậy, bắt const char* như vậy là nanny

Florastamine viết 18:37 ngày 01/10/2018

Compiler cho viết char *s = "abc"; không có nghĩa là nên viết char *s = "abc";. Bởi vì abc luôn nằm trong phần read-only section (.rodata) của chương trình, abc mặc định không đc đổi -> thêm const để nhấn mạnh ý đó.

viết 18:35 ngày 01/10/2018

GCC nó cho phép ko có nghĩa là nó đúng. Thế bạn có viết kiểu này ko?

int& two = 2;

ko bao giờ đúng ko? Vì 2 là hằng số, two là biến thay đổi được lại tham chiếu tới hằng số, vậy là sai. Tương tự về mặt logic, “hello” là hằng mảng ký tự, vậy tại sao lại cho phép biến thay đổi được lại trỏ tói “hello” được? Chỉ vì mảng ký tự có tồn tại trên vùng nhớ nên bạn được quyền trỏ lung tung bất chấp ko thay đổi giá trị vùng nhớ đó được? const char[6] decay thành const char*, nhưng const char* khác với char*, ai cho phép bạn tự tiện ép kiểu const thành non-const? Trỏ tới vùng ko thay đổi được phải ghi con trỏ tới const char rõ ràng, Ko có const trình dịch phải la làng là đúng. Nói “sốc” hơn 1 tí là trình dịch nào ko la thì uninstall nó, nói sốc như vậy để gây ấn tượng mạnh dẫn tới nhớ lâu hơn là trình dịch này dỏm ở chỗ này, ko nhất thiết phải uninstall nó, nhưng ai làm theo thì cũng được thôi =)

bạn nói “miễn là người sử dụng hiểu rõ và chú ý không thay đổi nội dung mà con trỏ *s trỏ tới là được” vậy đẻ ra keyword const làm gì nữa, cứ để người sử dụng tự quyêt là được? Nói rộng ra hơn nữa đẻ ra keyword private, protected trong class làm chi cho mất công vậy, người dùng tự biết được rồi. Đẻ ra mấy từ khóa này là để người sử dụng ko tự chỉa súng vô hạ bộ của họ, họ đi đứng thì ko sao chứ cuối xuống lụm tờ $100 là tàn đời trai ngay.

GCC thì chỉ cần thêm -pedantic-errors vào là nó la to hơn. Nếu bạn rảnh hơi hơn nữa thì phải sửa cho hết warning, chứ ko chỉ sửa hết error là được. Khi biên dịch 1 chương trình nó ói ra hằng trăm warnings thì mọi người sẽ nghĩ gì về người viết chương trình đó? Lười biếng? Viết code ẩu? Ko thèm quan tâm tới chất lượng code? 1 số trường hợp lờ warning đi là sai lầm: vd trong C viết gets(line) được ko có nghĩa là nó an toàn, trình dịch điêu thì nó chỉ nói nhỏ warning cho mình lờ đi, trình dịch tốt bụng thì nó la làng thành error bắt mình phải sửa. Nó to mồm khó chịu hơn nhưng nó giúp mình viết code ít sai hơn. Lâu lâu rảnh rỗi thì đi tìm mấy cái flag warning về thêm vào cho nó la ỏm tỏi lên =), lúc đó mới biết code ngu như thế nào.

Pham Van Hai viết 18:39 ngày 01/10/2018

int& two = 2;

Bạn ơi đang là tag C, không phải C++. Và chuẩn C vẫn cho phép dùng char *str = "a";.

viết 18:26 ngày 01/10/2018

vậy sửa lại thành

const int TWO = 2;
int* two = &TWO;

sai về mặt logic, còn nói là biên dịch được chạy được thì cũng được thôi, C mà, thích viết gì chả được

#include  <stdio.h>

int main(void)
{
    const int TWO = 2;
    int* two = &TWO;
    *two = 3;
    printf("%d", TWO); //in ra 3, ko báo lỗi gì, C mà lị
    return 0;
}

trong C++

    char* s = "hello";
    const int TWO = 2;
    int* two = &TWO;

nó lại báo là

source_file.cpp:5:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
     char* s = "hello";
               ^
source_file.cpp:7:17: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
     int* two = &TWO;

char* thì coi là warning, int* thì coi là lỗi, lạy ông GCC.

ISO C++ forbids
forbid
warning thôi được rồi xD

rogp10 viết 18:33 ngày 01/10/2018

char* thì coi là warning, int* thì coi là lỗi, lạy ông GCC.

-std=c++11 ko trước đó thì chỉ mới deprecate thôi.

Bài liên quan
0