Sự khác biệt giữa const tĩnh và const là gì?


81

Sự khác biệt giữa static constvà là constgì? Ví dụ:

static const int a=5;
const int i=5;

Có sự khác biệt nào giữa chúng không? Khi nào bạn sử dụng cái này thay cho cái kia?



5
Đã bỏ phiếu để mở lại. "Bản sao" đang hỏi một câu hỏi hoàn toàn khác, dành riêng cho việc sử dụng bộ nhớ. Câu hỏi này hỏi một câu hỏi tổng quát hơn về sự khác biệt.
rmaddy

Câu trả lời:


56

Sự khác biệt là sự liên kết.

// At file scope
static const int a=5;  // internal linkage
const int i=5;         // external linkage

Nếu iđối tượng không được sử dụng bên ngoài đơn vị dịch nơi nó được định nghĩa, bạn nên khai báo nó với trình staticxác định.

Điều này cho phép trình biên dịch (có khả năng) thực hiện tối ưu hóa hơn nữa và thông báo cho người đọc rằng đối tượng không được sử dụng bên ngoài đơn vị dịch của nó.


8
+1 Sẽ thật tuyệt nếu bạn cũng có thể thêm ý nghĩa của nó nếu những khai báo đó nằm trong một hàm.
Praetorian

Bạn có chắc rằng const int i = 5;có liên kết bên ngoài ?? Trong C ++ nó không ...
Kerrek SB

4
@KerrekSB ở phạm vi tệp, vâng. (C99, 6.2.2p5) "Nếu khai báo mã định danh cho một đối tượng có phạm vi tệp và không có mã định danh lớp lưu trữ, thì liên kết của nó là bên ngoài."
ouah

13
@KerrekSB: C và C ++ không phải là cùng một ngôn ngữ. Đặc biệt, C constkhông liên quan gì đến C ++ const.
R .. GitHub NGỪNG TRỢ GIÚP ICE

Các trình biên dịch có thực sự tối ưu hóa dựa trên tĩnh không? Có vẻ như không an toàn khi cho rằng một đối tượng tĩnh không được sử dụng bên ngoài đơn vị dịch của nó vì nó vẫn có thể được truyền bởi hàm non-static hoặc được trỏ tới bởi một con trỏ toàn cục không tĩnh.
.

99

staticxác định khả năng hiển thị bên ngoài của một hàm hoặc tuổi thọ của các biến bên trong. Vì vậy, nó không có gì để làm với constper se.

const nghĩa là bạn không thay đổi giá trị sau khi nó đã được khởi tạo.

static bên trong một hàm nghĩa là biến sẽ tồn tại trước và sau khi hàm kết thúc.

staticbên ngoài một chức năng có nghĩa là phạm vi của ký hiệu được đánh dấu staticđược giới hạn trong tệp .c đó và không thể nhìn thấy bên ngoài nó.

Về mặt kỹ thuật (nếu bạn muốn tra cứu điều này), staticlà một định nghĩa lưu trữ và constlà một định nghĩa loại.


0

const int i = 5;
i giá trị bạn có thể sửa đổi bằng cách sử dụng một con trỏ nếu tôi được định nghĩa và khai báo cục bộ, nếu nó là static const int a = 5; hoặc const int i = 5; trên toàn cầu, bạn không thể sửa đổi vì nó được lưu trữ trong bộ nhớ RO trong Phân đoạn dữ liệu.

    #include <stdio.h>
   //const int  a=10;              /* can not modify */
   int main(void) {
   // your code goes here

   //static const int const a=10;   /* can not modify */
   const int  a=10; 
   int *const ptr=&a;
   *ptr=18;
   printf("The val a is %d",a);
   return 0;
} 

-1

Nó phụ thuộc vào việc các định nghĩa này có nằm bên trong một hàm hay không. Câu trả lời cho trường hợp bên ngoài một hàm được đưa ra bởi ouah, ở trên. Bên trong của một chức năng, hiệu ứng là khác nhau, được minh họa bằng ví dụ dưới đây:

#include <stdlib.h>

void my_function() {
  const int foo = rand();         // Perfectly OK!
  static const int bar = rand();  // Compile time error.
}

Nếu bạn muốn một biến cục bộ là "thực sự không đổi", bạn phải xác định nó không chỉ là "const" mà còn là "static const".


Nó biên dịch hoàn hảo cho tôi ... Nhưng tôi biết thật ngu ngốc khi có một biến const tĩnh trong trường hợp này.
DrumM

1
@DrumM nó không ngu ngốc. Trong trường hợp foobiến được khởi tạo lại mỗi lần my_function()được gọi, dẫn đến một giá trị ngẫu nhiên khác được gán. Trong trường hợp barbiến chỉ được khởi tạo một lần, lần đầu tiên my_function()được gọi dẫn đến việc gán cùng một giá trị cho thời gian tồn tại của chương trình. Do đó thời lượng lưu trữ tĩnh.
jb

1
Trên thực tế, khi phản ánh thêm, nó phụ thuộc vào việc chúng ta đang sử dụng C hay C ++. Câu hỏi được gắn thẻ C, trong trường hợp đó chúng tôi gặp lỗi biên dịch đối với việc gán bardo rand()không phải là hằng số thời gian biên dịch.
jb

1
@nibot bạn có thể làm rõ ý của bạn về "hiệu ứng là khác nhau" và "thực sự không đổi" liên quan đến đặc điểm kỹ thuật lưu trữ và chất lượng loại không?
jb
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.