C语言作用域与数组详解
作用域
作用域是程序中的一个区域,在该区域内定义的变量可以被访问,超出该区域则无法访问。在C语言中,变量可以在三个地方声明:
1. 局部变量
在函数或块内部声明的变量称为局部变量。
特点:
只能被该函数或代码块中的语句使用
在函数外部不可见
生命周期仅限于函数执行期间
示例:
c
#include <stdio.h>int main() {/* 局部变量声明 */int a, b;int c;/* 实际初始化 */a = 10;b = 20;c = a + b;printf("value of a = %d, b = %d and c = %d\n", a, b, c);return 0; }
2. 全局变量
在所有函数外部定义的变量称为全局变量。
特点:
在程序的整个生命周期中都保留其值
可以被程序中的任何函数访问
在声明之后,在整个程序中可用
示例:
c
#include <stdio.h>/* 全局变量声明 */ int g;int main() {/* 局部变量声明 */int a, b;/* 实际初始化 */a = 10;b = 20;g = a + b;printf("value of a = %d, b = %d and g = %d\n", a, b, g);return 0; }
3. 形式参数
函数参数定义中的变量称为形式参数。
特点:
在函数中被视为局部变量
优先于全局变量
示例:
c
#include <stdio.h>/* 全局变量声明 */ int a = 20;int main() {/* main函数中的局部变量声明 */int a = 10;int b = 20;int c = 0;printf("value of a in main() = %d\n", a);c = sum(a, b);printf("value of c in main() = %d\n", c);return 0; }/* 相加两个整数的函数 */ int sum(int a, int b) {printf("value of a in sum() = %d\n", a);printf("value of b in sum() = %d\n", b);return a + b; }
作用域优先级规则
当局部变量和全局变量同名时:
局部变量优先于全局变量
形式参数优先于全局变量
示例:
c
#include <stdio.h>/* 全局变量声明 */ int g = 20;int main() {/* 局部变量声明 */int g = 10;printf("value of g = %d\n", g); // 输出10,局部变量优先return 0; }
变量初始化
局部变量:
系统不会自动初始化
必须手动初始化,否则包含垃圾值
全局变量:
系统自动初始化
初始化规则:
int
类型初始化为 0char
类型初始化为 '\0'float
类型初始化为 0double
类型初始化为 0指针类型初始化为 NULL
良好实践: 总是初始化变量,避免不可预知的结果。
数组
数组是一种数据结构,可以存储相同类型元素的固定大小顺序集合。
1. 数组声明
语法:
c
type arrayName[arraySize];
示例:
c
double balance[10]; // 声明一个包含10个double类型元素的数组
2. 数组初始化
方式1:声明时初始化
c
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
方式2:省略大小(自动计算)
c
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
方式3:单独赋值
c
balance[4] = 50.0; // 为第5个元素赋值
数组索引:
第一个元素索引为0(基索引)
最后一个元素索引为数组大小减1
3. 访问数组元素
示例:
c
#include <stdio.h>int main() {int n[10]; // n是包含10个整数的数组int i, j;/* 初始化数组元素为0 */ for(i = 0; i < 10; i++) {n[i] = i + 100; // 设置位置i的元素为i + 100}/* 输出每个数组元素的值 */for(j = 0; j < 10; j++) {printf("Element[%d] = %d\n", j, n[j]);}return 0; }
4. 多维数组
C语言支持多维数组,最常见的是二维数组。
声明语法:
c
type arrayName[x][y]; // 二维数组 type arrayName[x][y][z]; // 三维数组
二维数组初始化:
c
// 方式1:明确分行初始化 int a[3][4] = { {0, 1, 2, 3}, // 第0行的初始化{4, 5, 6, 7}, // 第1行的初始化{8, 9, 10, 11} // 第2行的初始化 };// 方式2:连续初始化 int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
访问二维数组元素:
c
int val = a[2][3]; // 获取第3行第4列的元素
二维数组示例:
c
#include <stdio.h>int main() {/* 一个5行2列的数组 */int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6}, {4,8} };int i, j;/* 输出每个数组元素的值 */for(i = 0; i < 5; i++) {for(j = 0; j < 2; j++) {printf("a[%d][%d] = %d\n", i, j, a[i][j]);}}return 0; }
5. 数组作为函数参数
三种声明方式:
方式1:指针作为形式参数
c
void myFunction(int *param) {// 函数体 }
方式2:指定数组大小
c
void myFunction(int param[10]) {// 函数体 }
方式3:不指定数组大小
c
void myFunction(int param[]) {// 函数体 }
实际示例:
c
#include <stdio.h>/* 函数声明 */ double getAverage(int arr[], int size);int main() {/* 包含5个元素的int数组 */int balance[5] = {1000, 2, 3, 17, 50};double avg;/* 传递数组指针作为参数 */avg = getAverage(balance, 5);/* 输出返回值 */printf("Average value is: %f\n", avg);return 0; }/* 计算平均值的函数 */ double getAverage(int arr[], int size) {int i;double avg;double sum = 0;for(i = 0; i < size; ++i) {sum += arr[i];}avg = sum / size;return avg; }
6. 从函数返回数组
C语言不允许直接返回整个数组,但可以返回指向数组的指针。
重要注意事项:
不能返回局部变量的地址
必须将局部变量声明为
static
示例:
c
#include <stdio.h> #include <stdlib.h> #include <time.h>/* 生成并返回随机数的函数 */ int *getRandom() {static int r[10];int i;/* 设置种子 */srand((unsigned)time(NULL));for(i = 0; i < 10; ++i) {r[i] = rand();printf("r[%d] = %d\n", i, r[i]);}return r; }/* 主函数 */ int main() {int *p; // 指向int的指针int i;p = getRandom();for(i = 0; i < 10; i++) {printf("*(p + %d) : %d\n", i, *(p + i));}return 0; }
7. 指向数组的指针
数组名是指向数组第一个元素的常量指针。
重要概念:
balance
指向&balance[0]
*(balance + 4)
等同于balance[4]
示例:
c
#include <stdio.h>int main() {/* 包含5个元素的数组 */double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};double *p;int i;p = balance; // p指向数组的第一个元素/* 使用指针输出数组元素的值 */printf("Array values using pointer\n");for(i = 0; i < 5; i++) {printf("*(p + %d) : %f\n", i, *(p + i));}/* 使用数组名作为地址输出数组元素的值 */printf("Array values using balance as address\n");for(i = 0; i < 5; i++) {printf("*(balance + %d) : %f\n", i, *(balance + i));}return 0; }
总结
作用域规则:
局部变量只在定义它们的函数或块中可见
全局变量在整个程序中可见
形式参数在函数中作为局部变量处理
数组特性:
存储相同类型元素的集合
支持一维和多维数组
可以通过指针操作
可以作为函数参数传递
可以通过返回指针从函数返回
最佳实践:
总是初始化变量
注意数组边界,避免越界访问
理解指针和数组的关系
在多维数组中正确使用嵌套循环
掌握作用域和数组的概念对于编写结构良好、高效的C语言程序至关重要。