2016-11-14 24 views
5

Tôi đã tìm thấy một thực tế thú vị và tôi không hiểu nó hoạt động như thế nào.
Đoạn mã sau đây hoạt động hoàn hảo.Kích thước mảng với biến const trong C

#include <stdio.h> 
int main(){ 
    const int size = 10; 
    int sampleArray[size]; 
    typedef char String [size]; 
    return 0; 
} 

Sau đó, tôi đã cố gắng chỉ sử dụng và chỉ biến cố định có phạm vi toàn cầu và vẫn ổn.

#include <stdio.h> 
const int size = 10; 
int main(){ 
    int sampleArray[size]; 
    typedef char String [size]; 
    return 0; 
} 


Nhưng, nếu tôi thay đổi phạm vi của mảng để toàn cầu là tốt, tôi đã nhận như sau:

error: variably modified ‘sampleArray’ at file scope

#include <stdio.h> 
const int size = 10; 
int sampleArray[size]; 
typedef char String [size]; 
int main(){ 
    return 0; 
} 

Và tôi đã không nhận được nó! Nếu tôi thay thế biến const cho ví dụ cũ. đến #define cũng sẽ ổn thôi.
Tôi biết rằng biến #define đã được xử lý trước và theo như tôi biết biến const chỉ là chỉ đọc. Nhưng điều gì làm cho phạm vi toàn cầu sau khi tất cả?

Tôi không hiểu vấn đề với đoạn mã thứ ba là gì, nếu điều thứ hai là không sao.

+3

Một số chi tiết: C có các đối tượng 'const' nhưng không phải là đối tượng _constant_. Mặc dù 'const' dường như ngụ ý _constant_, một đối tượng' const' không phải là _constant_, nhưng giống như "đối tượng này không nên thay đổi, nhưng nếu thay đổi được thử - ai biết điều gì có thể xảy ra?" Trong C, một _constant_ đúng là mã như '42', là hằng số _integer_ với kiểu' int'. Do đó 'const int size = 10;' không phải là biến _constant_. – chux

+0

Mảng không có kích thước không đổi, nhưng là mảng có độ dài thay đổi. – Olaf

+1

Giống như họ đã nói, C có các đối tượng 'const', đó là các biến * chỉ đọc thực *. Cf. C++, trong đó có các đối tượng 'const' thực sự là các hằng số * thời gian biên dịch *. –

Trả lời

6

Mảng thời lượng biến đổi Mảng có thể chỉ có thời lượng lưu trữ tự động. VLAs được giới thiệu trong C99.

Không được phép để khai báo một VLA với thời hạn lưu trữ tĩnh vì kích thước của VLA được xác định được tại thời gian chạy (xem dưới đây)

Trước khi tiêu chuẩn này, bạn có thể sử dụng một macro như

#define SIZE 10 

//... 

int a[SIZE]; 

hoặc một Enumerator của một liệt kê như

enum { SIZE = 10; } 

//... 

int a[SIZE]; 

bởi theo cách bạn có thể loại bỏ các vòng loại const và chỉ cần viết

int size = 10; 

thay vì

const int size = 10; 

(Trong C++, bạn phải sử dụng vòng loại const dù trong C++ không có Vlas ngoại trừ một số trình biên dịch có thể có phần mở rộng ngôn ngữ riêng của họ)

Đi vào tài khoản rằng toán tử sizeof cho VLAs được tính toán vào thời gian chạy thay vì biên dịch.

+0

Cảm ơn bạn tôi vừa mới bắt đầu hiểu thêm một chút! Tuy nhiên, nếu tôi cố gắng mà không có const, tôi đã có lỗi tương tự với phạm vi toàn cầu. Nhưng với #define SIZE 10, nó hoạt động. –

+0

@ BálintPap Như tôi đã viết VLAs có thể không có thời gian lưu trữ tĩnh mà tất cả các mảng toàn cầu có. –

+0

A, ở đây chúng tôi đi, được rồi! Vâng, không bao giờ nghĩ về điều đó. Cảm ơn bạn đã giải thích của bạn! Tôi đánh giá cao nó! –

Các vấn đề liên quan