1、实参和形参:
测试代码:
#include <stdio.h>
// 实参(actual parameters)是调用函数时传递给函数的参数,
// 而形参(formal parameters)是函数定义中声明的参数,用于接收实参的值。
// 函数1:打印两个整数的和
void printSum(int a, int b) { // a和b是形参
int sum = a + b;
printf("The sum of %d and %d is %d\n", a, b, sum);
}
// 函数2:返回两个整数的乘积
int multiply(int x, int y) { // x和y是形参
return x * y; // 返回乘积
}
// 函数3:根据给定的基数和指数计算幂
int power(int base, int exponent) { // base和exponent是形参
int result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result; // 返回计算得到的幂
}
int main() {
// 调用printSum函数,5和3是实参
printSum(5, 3);
// 调用multiply函数,并将结果存储在变量product中
int product = multiply(10, 2); // 10和2是实参
printf("The product of 10 and 2 is %d\n", product);
// 调用power函数,计算2的3次幂,并将结果存储在变量result中
int result = power(2, 3); // 2和3是实参
printf("2 to the power of 3 is %d\n", result);
return 0;
}
运行结果如下:
2、数组作为参数传递:
测试代码:
#include <stdio.h>
// 数组作为函数的参数时,并不是将整个数组作为参数传递给函数,而是传递数组的首地址(即数组第一个元素的地址)。
// 函数声明,数组作为参数。
void printArray(int arr[], int size);
// 函数声明,参数类型实际上是int指针
// void printArray(int* arr, int size);
void printAndModifyArray(int arr[], int size);
int main() {
int myArray[] = {1, 2, 3, 4, 5};
//数组的大小不是通过数组参数自动传递的,需要作为额外的参数传递。
int size = sizeof(myArray) / sizeof(myArray[0]); // 计算数组的大小
// 调用函数,传递数组和大小
printArray(myArray, size);
// 调用函数,传递数组和大小,函数将修改数组并打印修改后的值
printAndModifyArray(myArray, size);
return 0;
}
// 函数定义,arr实际上是int*类型,即指向int的指针
// 多数情况下,数组名被当作指向其首元素的指针。
void printArray(int arr[], int size) {
for(int i = 0; i < size; i++) {
//由于传递的是数组的地址,因此在函数内部对数组元素的修改会影响到原始数组。
printf("%d ", arr[i]); // 通过数组下标访问数组元素
//printf("%d ", *(arr + i)); //通过指针访问数组元素
}
printf("\n");
}
// 函数定义,arr作为函数参数时,实际上是int*类型,即指向int的指针
void printAndModifyArray(int arr[], int size) {
// 修改数组元素的值
for(int i = 0; i < size; i++) {
// 给每个元素加上10
arr[i] += 10;
// 或者使用指针运算修改
// *(arr + i) += 10;
// 打印修改后的值
printf("%d ", arr[i]);
}
printf("\n");
}
运行结果如下:
3、查找一维数组中的最小值:
测试代码:
#include <stdio.h>
// 函数声明,参数为指向int的指针和数组的大小
int findMinValue(int arr[], int size);
int main() {
int n, i;
int arr[100];
// 获取用户输入数组的大小
printf("请输入n的值(n个元素的数组): ");
if (scanf("%d", &n) != 1 || n <= 0 || n > 100) {
printf("输入错误:数组大小必须在1到100之间。\n");
return 1; // 退出程序
}
// 填充数组
for (i = 0; i < n; i++) {
printf("请输入arr[%d]的值: ", i);
if (scanf("%d", &arr[i]) != 1) {
printf("输入错误:无法读取所有数组元素。\n");
return 1; // 退出程序
}
}
// 调用函数查找最小值
int minValue = findMinValue(arr, n);
// 输出最小值
printf("数组中的最小值是: %d\n", minValue);
return 0;
}
// 函数定义,查找数组中的最小值
int findMinValue(int arr[], int size) {
int minValue = arr[0]; // 假设第一个元素就是最小值
for (int i = 1; i < size; i++) {
if (arr[i] < minValue) {
minValue = arr[i]; // 更新最小值
}
}
return minValue; // 返回找到的最小值
}
运行结果如下:
4、查找二维数组中的最小值:
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 函数声明
int findMinValue(int **arr, int size);
int main() {
int n, i, j;
int **arr; // 指向指针的指针,用于动态创建二维数组
// 获取用户输入n的值(n*n的二维数组)
printf("请输入n的值(n*n的二维数组): ");
if (scanf("%d", &n) != 1 || n <= 0) {
printf("输入错误:n必须是一个正整数。\n");
return 1; // 退出程序
}
// 动态分配二维数组的内存
arr = (int **)malloc(n * sizeof(int *)); // 分配指针数组
if (arr == NULL) {
printf("内存分配失败。\n");
return 1; // 退出程序
}
for (i = 0; i < n; i++) {
arr[i] = (int *)malloc(n * sizeof(int)); // 为每一行分配内存
if (arr[i] == NULL) {
printf("内存分配失败。\n");
// 释放已分配的内存
for (j = 0; j < i; j++) {
free(arr[j]);
}
free(arr);
return 1; // 退出程序
}
}
// 初始化随机数种子
srand((unsigned)time(NULL));
// 生成n*n的二维数组并填充随机数
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
arr[i][j] = rand() % 100; // 生成0到99之间的随机数
// 可选:打印数组
printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
}
}
// 调用函数查找最小值
int minValue = findMinValue(arr, n);
// 输出最小值
printf("数组中的最小值是: %d\n", minValue);
// 释放二维数组的内存
for (i = 0; i < n; i++) {
free(arr[i]);
}
free(arr);
return 0;
}
// 函数定义,查找二维数组中的最小值
int findMinValue(int **arr, int size) {
int minValue = arr[0][0]; // 假设第一个元素就是最小值
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (arr[i][j] < minValue) {
minValue = arr[i][j]; // 更新最小值
}
}
}
return minValue; // 返回找到的最小值
}
运行结果如下:
..........................................................................................................................................................
6、变量的作用域:
变量的作用范围(也称为作用域)是指变量在程序中可以被访问的区域。C语言中的变量作用域主要分为以下几种:
全局变量(Global Variables):
定义在函数外部的所有变量(即在所有函数之外定义的变量)称为全局变量。
全局变量的作用域从定义它的点开始,到文件结束。如果全局变量在另一个文件中声明为extern,则它也可以在该文件中被访问。全局变量可以被程序中所有的函数访问。
局部变量(Local Variables):
定义在函数内部的变量称为局部变量。
局部变量的作用域从定义它的点开始,到包含它的代码块(大括号{}内的区域)结束。
局部变量只能在其被声明的代码块内部访问。一旦离开该代码块,局部变量就会被销毁,并且不能被访问。
块作用域变量(Block-scoped Variables):
块作用域变量通常指的是局部变量,因为局部变量的作用域被限制在它们被声明的代码块内。
C99标准引入了for循环的初始化表达式中声明的变量的块作用域。
函数原型作用域(Function Prototype Scope):
在C语言中,实际上并不直接存在所谓的“函数原型作用域”。当在函数原型中声明参数时,参数在函数原型声明的上下文中是可见的,但它们的作用域并不扩展到整个文件或函数内部。函数原型本身主要用于声明函数的存在和参数类型,不是为了创建具有特定作用域的新变量。
静态存储期变量(Static Variables):
函数内部使用static关键字声明变量时,这些变量具有静态存储期,但它们的作用域仍然局限于声明它们的函数内部(对于局部变量)或文件内部(对于全局变量)。静态变量的值在程序执行期间保持不变,即使函数调用结束也不会被销毁。如果函数被多次调用,静态变量的值将保持其最后一次被修改的值。
测试代码:
#include <stdio.h>
// 全局变量
int globalVar = 10;
// 函数原型声明
void printGlobalVar();
void modifyGlobalVar();
void funcWithLocalAndStaticVars();
int main() {
// 静态局部变量(在main函数中)
static int staticLocalMainVar = 20;
printf("在main函数中访问全局变量(初始值): %d\n", globalVar);
printf("在main函数中访问静态局部变量(初始值): %d\n", staticLocalMainVar);
modifyGlobalVar();
printf("在main函数中访问全局变量(修改后): %d\n", globalVar);
funcWithLocalAndStaticVars();
funcWithLocalAndStaticVars(); // 再次调用以展示静态局部变量的持久性
printf("在main函数中访问静态局部变量(main的): %d\n", staticLocalMainVar);
return 0;
}
// 修改全局变量的函数
void modifyGlobalVar() {
globalVar = 100; // 全局变量可以在函数间共享和修改
}
// 局部和静态局部变量的函数
void funcWithLocalAndStaticVars() {
// 局部变量
int localVar = 30;
printf("在funcWithLocalAndStaticVars函数中访问局部变量: %d\n", localVar);
// 静态局部变量(在函数内部)
static int staticFuncVar = 50;
printf("在funcWithLocalAndStaticVars函数中访问静态局部变量(首次或再次调用): %d\n", staticFuncVar);
// 修改静态局部变量的值(仅在首次调用时明显)
staticFuncVar += 10;
// 块作用域变量
{
int blockScopedVar = 40;
printf("在funcWithLocalAndStaticVars函数中的块内访问块作用域变量: %d\n", blockScopedVar);
}
// blockScopedVar 在这里之后将不可访问
}
运行结果如下: