八、函数
在C中 函数是这样的:
void hello(int id)
{
printf("Hello!%d",id);
}
C不像Java 在C中定义函数的时候不需要权限修饰符 只有返回类型和函数名
和Java一样 在C中也是使用return
来返回值
int calc(int count)
{
int newCount=count-1;
return newCount;
}
🎈函数的先后关系
C的编译器是按照代码书写顺序自上而下按顺序分析代码的
因此 要将函数定义在主函数(main)的上面 使得C先知道代码中的函数
这样 当main中需要调用的时候 才能执行对应的函数
否则 若是main函数在上面 函数书写在下面 那么在执行函数的时候 C是不知道下面有没有对应的函数的 在编译的时候可能会报错
因此 若想让主函数(main)写在代码的上面 必须让C先了解代码中有哪些函数 需将函数的原型声明放在main的上面
比如:
#include <stdio.h>
// 函数的原型声明 以分号结尾
int calc(int count);
int main()
{
int a=5;
int b;
b=calc(a);
printf("%d",b);
}
// 函数的定义
int calc(int count)
{
int newCount=count-1;
return newCount;
}
声明并不是函数 只是先告诉C编译器有这么一个函数
在编译到了函数的定义的时候还会再对声明进行一次校验
因此 必须保证函数的声明和定义完全一致
在函数的原型声明中还可以不带有入参的名称 只要有参数类型即可
比如:
int calc(int);
但为了方便阅读代码 最好还是带上参数的名称
如果函数没有参数 建议在参数里面写上void 而不要留空
留空意味着并不一定是没有参数 而是函数的参数表未知
因此 当参数留空时 C会进行猜测 从而导致可能会产生一些类型转换的问题
🚩当参数的类型不匹配时
在C语言中 调用函数时所给的值与参数的类型可以不匹配
编译器会自动将类型进行转换 但可能不会给出错误提示 因此可能会出现一些问题
C语言在调用函数时 永远只能传值给函数 而不是传变量
🎈本地变量的规则
-
本地变量定义在块中 可以是函数的块 语句的块 甚至是随意一对花括号
在程序运行进入到这个快的区域内之前 其中的变量是不存在的
在离开这个块之后 其中的变量就消失了 -
块的外部定义的变量在块的里面仍然是有效的 仍然可以使用
-
在块的内部 若定义了一个和外部同名的变量 那么会掩盖外面的变量 (个人觉得掩盖比覆盖用词更为妥当)
在块内部使用时 使用的是在块内部定义的那个变量 而不是外部的同名变量 (然而在Java中就不行了 因此这是C和Java的一个区别)
当到了块的外部后 则外面的变量又会生效了
另 需要注意的是 在C语言中 不允许函数的嵌套
也就是不允许在一个函数的函数体内放入另外一个函数的函数体
但是可以放入另一个函数的声明
main() 是程序的入口 也是一个函数
同样 在main中 需要返回一个值 作为程序的状态码
在传统程序中 若返回0 则代表正常运行 若返回非0 则代表出现了一些异常
int main()
{
return 0;
}
九、数组
🎈一维数组
🚩定义数组
格式:<类型> 变量名[数量];
例如:
int count[100]; // 定义一个长度100的类型为int的名称为count的数组
double height[20]; // 定义一个长度20的类型为double的名称为height的数组
注:在C99之前 元素数量必须是编译时确定的字面量 不能是变量
数组一旦创建 无法改变数组的大小
数组中的元素在内存中是紧密地依次排列的
如果定义一个数组:int i[100];
那么 每个单元就是i[n]
在赋值号=
的左边的是左值 在右边的是右值
在C语言中 无论是编译器还是运行环境 都不会检查代码中的数组下标是否越界(无论是读操作还是写操作)
因此 一旦程序运行了 则越界的数组操作可能导致程序出现问题
数组集成初始化
对于数组 还有一种初始化的方式 就是在创建数组的时候给定数组中所有的值
比如:
int i[]={1,2,3,4,5,6,7,8};
(当然 在Java中也有这种初始化的方式)
如果这么定义:
int i[10]={1};
那么 数组 i 的内部是这样的:1 0 0 0 0 0 0 0 0 0
若未设置值 那么默认会将数组中值设为0
集成初始化的定位
在C99中 还可以使用定位来给数组赋初始值
比如:
int i[10]={
[1]=12,[3]=21,36
}
上述代码的意思是:为数组 i 中的第二项赋初始值为12 为第四项赋初始值为21 为第五项赋初始值为36
🚩数组的大小和长度
在C中 使用sizeof来获取整个数组所占据的内容的大小(单位为字节)
在C中不像Java有length能直接获取数组的长度 但可以间接获得
用数组的大小除以数组中第一个单位的大小 (因为数组中每个单位的大小都是相同的):
int i[6];
// 数组的大小
printf("%d\n",sizeof(i)); // 24
// 数组中第一个单位的大小
printf("%d\n",sizeof(i[0])); // 4
// 数组的长度
printf("%d\n",sizeof(i)/sizeof(i[0])); // 6
🚩数组的赋值
数组不能直接赋值 比如:
int a[]={1,2,3};
int b[]=a;
数组变量本身不能被赋值
若要将一个数组中的所有元素交给另一个数组 那么必须采用遍历 这是唯一的方式
在C中 数组在作为函数的参数传入时 必须再用另一个参数来传入该数组的大小
因为 在函数中 不能再使用sizeof来计算数组的元素个数了
🎈二维数组
🚩定义数组
格式:<类型> 变量名[行数量][列数量];
例如:
int count[3][5]; // 定义一个3行5列的类型为int的名称为count的数组(矩阵)
数组集成初始化
int i[][5]=[
{1,2,3,4,5},
{6,7,8,9,10}
];
在初始化的时候 必须给出列数
若省略 则表示后面的值补为默认的0
也可以写成一行 就像一维数组一样:
但是不方便阅读
int i[][3] = {1,2,3,4,5,6,7,8,9};
相当于
int i[][3]=[
{1,2,3},
{4,5,6},
{7,8,9}
];
当然 在C99中 也可以可以使用定位来给二维数组赋初始值