函数声明
如下函数声明,如果想让函数正常执行,需要将函数写在main函数上面;如果函数写在main函数下面或者是其它c文件里面,需要在main函数上面写上void test02(); 就是返回值类型加函数名加括号,有参数也要写上参数;
void test2() {
float f = 3.14159265358979323846f;
double d = 3.14159265358979323846;
printf("%f\n",f); // 3.141593 默认保留6位小数
printf("%.2f\n",f); // 3.14 指定保留2位小数
printf("%.10f\n",f); // 3.1415927410 明显发现与原先小数点不太一样
printf("%.10lf\n",d); // 3.1415926536 这样就一样了
printf("%*f\n",2,f); // 精度的其它表示方法
}
void test07();
int main() {
/*
* 函数声明
* C是自上而下执行的
* test02需要写在调用此函数的上面
*/
test2();
test07();
}
函数声明有这么几个注意点
- 函数声明中参数形参变量名称可以不写
- 函数在main函数内部声明也可以,在该函数调用之前声明都可以
函数递归案例1
void test03() {
/*
* 需求:
* 分别使用循环结构和递归
* 实现验证用户输入密码功能
*/
int pwd = -1;
do{
printf("please insert password\n");
scanf("%i",&pwd);
}while (pwd != 123456);
printf("welcome back");
}
void test04() {
int pwd = -1;
int cpassword = 123456;
printf("please insert password\n");
scanf("%i",&pwd);
if (pwd != cpassword) {
test04();
}
/*
* 假设密码输入错误次数为n次
* 那么下面这行代码实行次数是n+1次
* 这是一个注意点
*/
printf("welcome back");
}
函数递归注意点
- 假设密码输入错误,函数会进入if条件语句,(就会再次进行压栈操作),而此时在栈最底部的test04程序还未执行完,需要等新压入的test04程序执行完才能继续执行
- 如果输入密码错误的次数是n次,那么会开辟n+1个存储空间
函数递归案例2
/**
* 求base的n次方
* @param base
* @param n
* @return
*/
int pow(int base,int n) {
if (n == 0) {
return 1;
}else{
return pow(base,n - 1) * base;
}
}
数组的存储细节
/*
* C数组
* 数组是一组相同类型的数据的有序集合
*
* 数组存储细节
* * 分配存储空间的时候是从数组占用存储空间最小开始分配
* * 存储数据和变量存储一样,也是从索引最高的开始存储
*/
int ages[3];
ages[0] = 1;
ages[1] = 3;
ages[2] = 5;
数组的注意点
/*
* 1. 在老版本的C语言标准中,元素的个数只能是常量,不能是变量
* 在新版本的C语言标准中,元素的个数可以是常量也可以是变量,但是不能在定义数组的时候进行初始化
* 在企业开发中,数组定义基本使用常量
* 2. 不要超出数组的存储范围
* 3. 数组名作为函数的参数,在函数内修改形参,会影响到函数外的实参,是因为数组形参直接指向了原始数组的存储地址
*/
char ch1s[2] = {'a','b'};
char ch2s[2] = {'c','d'};
printf("%c\n",ch2s[0]); // c
printf("%c\n",ch2s[1]); // d
printf("%c\n",ch2s[2]); // a
// 输出a的原因:访问ch2s[2]时,由于超出存储范围,向上面的地址查找,结果查到了ch1s[0]
外部函数遍历数组
void printArray(int values[5],int len) {
/*
* 数组长度 = 数组总大小 / 数组任意元素大小
*/
// int len = sizeof(values) / sizeof(values[1]);
for (int i = 0; i < len; i++) {
printf("%i\t",values[i]);
// 1 2 3 4 5
}
}
int main() {
int nums[5] = {1,2,3,4,5};
int len = sizeof(nums) / sizeof(nums[0]);
/*
* 此处传递指针类型
* * 指针类型在32位编译器下占4个字节,64位编译器下占8个字节
* * 在函数中sizeof计算出来的是指针类型的大小,而不是数组类型的大小
* * 在外面求出来的是数组大小,里面求的是地址大小
* * 所以以后想在函数里面遍历数组,需要传递第2个参数len,就是在外面算的数组的大小
*/
printArray(nums,len);
return 0;
}
数组默认值
/*
* 如果只定义了变量,并没有初始化数据
* * 此时变量默认存储垃圾数据,并且在打印输出时会呈现褐色高亮显示
* * 数组也是一样,必须初始化,否则保存的就是垃圾数据
* * 如果定义的同时进行初始化,那么被初始化的元素初始化为指定数据,未被初始化的元素默认为0
*/
数组练习1求数组中的最大值
/*
* 数组练习
* 需求:定义一个函数,求出数组中的最大值
*/
/**
* 求出数组中最大值
* @param value 数组的地址
* @return
*/
int getMaxNum(int nums[6],int len) {
// 假设最大值是第1个元素
int max = nums[0];
for (int i = 0; i < len; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
return max;
}