30/09/2018, 19:10

Giải thích biến toàn cục và biến cục bộ trong ví dụ sau

#include <stdio.h>
#include <conio.h>
int x=9;
int main(){
	int a=5, b=2;
	{
		int a=4;
		b=a+b;
		printf("a=%d b=%d x=%d",a,b,x);
		printf("
");
	}
	printf("a=%d b=%d x=%d",a,b,x);
	getch();
	return 0;
}

khi chạy chương trình xuất ra 2 dòng a=4 b=6 x=9, a=5 b=6 x=9
ai giải thích giùm mình dòng printf thứ 2 đi tại sao lại ra kết quả là a=5 b=6 x=9 mà không phải là a=5 b=2 x=9. Tại sao b=6?

Pham Van Hai viết 21:21 ngày 30/09/2018

Tại sao b = 6?
b được khai báo ở đầu hàm main nên pham vi hoạt động của nó trong toàn bộ hàm main, toàn bộ block thuộc hàm main.
Biến b ở đầu hàm main sẽ không được dùng, không thay đổi giá trị nếu:

  • Có khai báo một biến cục bộ trùng tên b ở một block (giống biến a) trong hàm main.
  • b được truyền vào 1 hàm theo giá trị (call by value).
Nguyễn Minh Trí viết 21:26 ngày 30/09/2018

@Pham_Van_Hai
từ dòng 6 đến dòng 11 mình gọi là block đúng không? biến trong block là biến a=4(mình gọi là biến cục bộ) khi thoát khỏi block thì giá trị a sẽ chết đi, vậy tại sao biến b=6 giá trị nó không chết đi mà lại đc sử dụng bên dưới block

Pham Van Hai viết 21:22 ngày 30/09/2018

Đúng, đó là block.
Vì không có biến cục bộ nào cùng tên b nào được khai báo trong block đó nên biến b ở đầu hàm main sẽ được dùng -> b đó có nghĩa trong toàn hàm main -> bất kỳ thay đổi gì điều được giữ nguyên -> nó chỉ mất đi khi thoát ra khỏi hàm main.
Còn trong block có một biến cục bộ cùng tên a được khai báo -> biến a trong block được dùng -> vì a chỉ có ý nghĩa trong block -> ra khỏi block nó bị mất đi.
Trong bất ký trường hợp nào biến (nếu trùng tên) có phạm vi nhỏ nhất sẽ được dùng đầu tiên (nếu có) -> rồi đến các biến có phạm vi rộng hơn.

PS: Hạn chế dùng trùng tên biến có phạm vi khác nhau -> tránh nhầm lẫn -> gây lỗi khó tìm.

Nguyễn Minh Trí viết 21:18 ngày 30/09/2018

@Pham_Van_Hai như vậy là trong 1 block có biến cục bộ cùng tên a được khai báo -> khi ra khỏi block nó sẽ mất đi, do trong block không có biến cục bộ cùng tên b được khai báo nên giá trị b=6 sẽ được giữ nguyên khi thoát khỏi block

Pham Van Hai viết 21:17 ngày 30/09/2018

Bạn đọc lại nhiều lần trả lời trước của mình đi nhé, mình nó rất rõ ràng từng trường hợp rồi.

Nguyễn Minh Trí viết 21:14 ngày 30/09/2018

@Pham_Van_Hai chắc tại mình chậm tiêu tks

lahata viết 21:19 ngày 30/09/2018

Theo mình hiểu là như vậy
Biên cục bộ (bình thường) là biến nằm trong 1 khối { }
Phạm vi của biến chỉ ở trong khối chứa nó, nếu có cùng tên thì khi sử dụng sẽ dụng biến nằm trong khối nhỏ nhất.

{
    int a = 5;
    {
        int a = 10;
        printf a; // in ra 10
        {
             print a; // in ra 10
             int b;
        }
        print b; //lỗi vì không nhìn thấy b
    }
    printf a; // sẽ in ra 5.
}

Ra khỏi khối { } biến đó không còn tác dụng

Nguyễn Minh Trí viết 21:15 ngày 30/09/2018

@taivh vì giá trị b trong khối {} mình chỉ gán giá trị(b=a+b) chứ không phải là khai báo (ví dụ int b=5) nên khi thoát khỏi khối {} biến đó vẫn còn tác dụng nên giá trị b sau block mới bằng 6

lahata viết 21:15 ngày 30/09/2018

Mình đính chính rõ hơn là biến có hiệu lực từ khi bạn khai báo.

main(){
	int b=2;
	{
		int a=4;
		b=a+b;  // b = 4 + 2 = 6
	}
       printf b; // in ra 6 là bình thường vì b nằm trong khối { } của hàm main (Khai báo
                  // trong dấu { } của main.
}
Nguyễn Minh Trí viết 21:17 ngày 30/09/2018

b nằm trong khối { } không phải là khai báo mà là chỉ là phép gán nên khi ra khỏi khối nó vẫn còn tác dụng nên printf b mới bằng 6. nếu mình khai báo biến b trong khối {} là 6 thì khi thoát khỏi khối {} thì giá trị b =6 không còn nữa, lúc này kết quả b sẽ bằng 2

main(){
	int b=2;
	{
		int a=4;
		int b =6;
	}
       printf b; // b =2
}
Bài liên quan
0