1 函数
1.1 定义函数
每个 C 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。
1.2 函数声明
函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
```c
//以下两种都可以,参数名称不重要,参数类型很重要
int max(int num1, int num2);
int max(int, int);
```
1.3 函数参数
如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。 当调用函数时,有两种向函数传递参数的方式:
1.4 案例
#include<stdio.h>
double getAverage(int arr[], int size);
int main()
{
int arr[5] ={233,500,5,56,34};
double avg = getAverage(arr,5);
printf("平均数为%f",avg);
}
double getAverage(int arr[],int size){
int i;
double avg = 0;
double sum =0;
for(i=0;i<size;i++){
sum += arr[i];
}
printf("和为%f",sum);
avg = sum/size;
return avg;
}
或者
#include<stdio.h>
double getAvg(int arr[],int size);
int main(){
int arr[] = {7,7,7,7,7,7};
printf("数组的平均值为%f \n",getAvg(arr,sizeof(arr)/sizeof(arr[0])));
}
double getAvg(int arr[4],int size){
int sum =0;
int i=0;
for(i=0;i<size;i++){
sum+=arr[i];
}
printf("数组总和为sum=%d \n",sum);
return sum/size;
}
2. 循环和数组
2.1 数组的定义
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
上述都是正确的。
案例
#include<stdio.h>
int main()
{
int n[10];
int i;
int j;
for(i=0;i<10;i++){
n[i]=i+100;
}
for(j=0;j<sizeof(n)/sizeof(n[0]);j++){
printf("打印数组为%d",n[j]);
printf("\n");
}
return 0;
}
注意输出:
注意点:
- 数组长度获取:
sizeof(n)/sizeof(n[0]) ,含义是数组字节总长度/一个字节长度,该方式不能用于函数形参数组。 - 数组的循环变量定义要在外面进行定义。
2.2 传递数组给函数
方式 1 形式参数是一个指针。
void myFunction(int *param)
{
.
.
.
}
方式 2 形式参数是一个已定义大小的数组。
void myFunction(int param[10])
{
.
.
.
}
方式 3 形式参数是一个未定义大小的数组。
void myFunction(int param[])
{
.
.
.
}
2.3 从函数返回数组
C 语言不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。 如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:
int * myFunction()
{
.
.
.
}
另外,C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
#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 i;
p = getRandom();
for(i=0;i<10;i++){
printf("*(p+%d) = %d \n",i,*(p+i));
}
return 0;
}
2.4 指向数组的指针
double *p;
double balance[10];
p = balance;
#include<stdio.h>
int main()
{
double arr[5] ={1,2,3,4,5};
double *p;
int i;
p = arr;
printf("打印出指针p的值= %p,指针p所指向数组元素的值=%f\n",p,*p);
printf("使用指针打印出数组值\n");
for(i=0;i<5;i++){
printf("*(p+%d): %f\n",i,*(p+i));
}
printf("使用arr作为地址打印出数组值\n");
for(i=0;i<5;i++){
printf("*(arr+%d): %f\n",i,*(arr+i));
}
}
输出结果
打印出指针p的值= 0060FEF0,指针p所指向数组元素的值=1.000000
使用指针打印出数组值
*(p+0): 1.000000
*(p+1): 2.000000
*(p+2): 3.000000
*(p+3): 4.000000
*(p+4): 5.000000
使用arr作为地址打印出数组值
*(arr+0): 1.000000
*(arr+1): 2.000000
*(arr+2): 3.000000
*(arr+3): 4.000000
*(arr+4): 5.000000
请按任意键继续. . .
3. 枚举的使用
3.1 枚举的定义
语法:
enum 枚举名 {枚举元素1,枚举元素2,……};
方式1: 先定义枚举类型,再定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
方式2: 定义枚举类型的同时定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
方式3: 省略枚举名称,直接定义枚举变量
enum
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
案例
#include<stdio.h>
enum DAY {
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
int main()
{
enum DAY day =WED;
printf("输出星期%d",day);
}
#include <stdio.h>
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
int main()
{
for (day = MON; day <= SUN; day++) {
printf("枚举元素:%d \n", day);
}
}
枚举在 switch 中的使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
enum color { red=1, green, blue };
enum color favorite_color;
printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): ");
scanf("%u", &favorite_color);
switch (favorite_color)
{
case red:
printf("你喜欢的颜色是红色");
break;
case green:
printf("你喜欢的颜色是绿色");
break;
case blue:
printf("你喜欢的颜色是蓝色");
break;
default:
printf("你没有选择你喜欢的颜色");
}
return 0;
}
4. 指针
4.1 指针的定义
#include <stdio.h>
int main ()
{
int var_runoob = 10;
int *p;
p = &var_runoob;
printf("var_runoob 变量的地址: %p\n", p);
return 0;
}
表示定义一个P指针,指向变量var_runoob,它的值是var_runoob的地址。
4.2 指针的使用
使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。 下面的实例涉及到了这些操作:
#include <stdio.h>
int main ()
{
int var = 20;
int *ip;
ip = &var;
printf("var 变量的地址: %p\n", &var );
printf("ip 变量存储的地址: %p\n", ip );
printf("*ip 变量的值: %d\n", *ip );
return 0;
}
打印:
var 变量的地址: 0x7ffeeef168d8
ip 变量存储的地址: 0x7ffeeef168d8
*ip 变量的值: 20
5. 指针的算术运算
- 指针的每一次递增,它其实会指向下一个元素的存储单元。
- 指针的每一次递减,它都会指向前一个元素的存储单元。
- 指针在递增和递减时跳跃的字节数取决于指针所指向变量数据类型长度,比如 int 就是 4 个字节。
5.1 递增一个指针
#include<stdio.h>
const int MAX = 3;
int main()
{
int var[] = {110,122,300};
int i, *pr;
pr = var;
for(i =0;i<MAX;i++){
printf(" var[%d]的存储地址=%p",i,pr+i);
printf(" var[%d]的存储值=%d\n",i,*(pr+i));
}
}
输出结果:
var[0]的存储地址=0060FF00 var[0]的存储值=110
var[1]的存储地址=0060FF04 var[1]的存储值=122
var[2]的存储地址=0060FF08 var[2]的存储值=300
请按任意键继续. . .
5.2 递减一个指针
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
ptr = &var[MAX-1];
for ( i = MAX-1; i >= 0; i--)
{
printf(" 存储地址:var[%d] = %p", i, ptr );
printf(" 存储值:var[%d] = %d\n", i, *ptr );
ptr--;
}
return 0;
}
5.3 指针的比较
指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
ptr = var;
i = 0;
while ( ptr <= &var[MAX - 1] )
{
printf("存储地址:var[%d] = %p\n", i, ptr );
printf("存储值:var[%d] = %d\n", i, *ptr );
ptr++;
i++;
}
return 0;
}
5.4 指针数组
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr[MAX];
for(i=0;i<MAX;i++){
ptr[i] = &var[i];
}
for(i=0;i<MAX;i++){
printf(" 存储地址:var[%d] = %p", i, ptr[i] );
printf(" 存储值:var[%d] = %d\n", i, *ptr[i] );
}
return 0;
}
输出结果:
存储地址:var[0] = 0060FF00 存储值:var[0] = 10
存储地址:var[1] = 0060FF04 存储值:var[1] = 100
存储地址:var[2] = 0060FF08 存储值:var[2] = 200
请按任意键继续. . .
也可以用一个指向字符的指针数组来存储一个字符串列表:
#include <stdio.h>
const int MAX = 4;
int main ()
{
const char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
int i = 0;
for ( i = 0; i < MAX; i++)
{
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
输出结果:
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali
请按任意键继续. . .
5.5 指向指针的指针
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。
int **var;
也就是说 指针的指针存放的时候上一个指针的地址。
#include <stdio.h>
int main ()
{
int V;
int *Pt1;
int **Pt2;
V = 100;
Pt1 = &V;
Pt2 = &Pt1;
printf("var = %d\n", V );
printf("Pt1 = %p\n", Pt1 );
printf("*Pt1指针所指向的值 = %d\n", *Pt1 );
printf("Pt2的值 = %p\n", Pt2 );
printf("**Pt2指针所指向的指针所指向的值 = %d\n", **Pt2);
return 0;
}
输出结果:
var = 100
Pt1 = 0060FF24
*Pt1指针所指向的值 = 100
Pt2的值 = 0060FF20
**Pt2指针所指向的指针所指向的值 = 100
请按任意键继续. . .
5.6 传递指针给函数
#include <stdio.h>
void getSecond(long *par);
int main ()
{
long sec = 0;
getSecond(&sec);
printf("实际输出值%ld\n",sec);
}
void getSecond(long *par){
*par = time(NULL);
}
输出结果:
实际输出值1632731782
请按任意键继续. . .
这是因为传过去的是地址,在方法中修改是同一份变量。
5.7 数组参数
#include <stdio.h>
double getAverage(int *arr, int size);
int main ()
{
int balance[5] = {100,200,300,400,500};
double avg;
avg = getAverage(balance,5);
printf("平均数为%f\n",avg);
}
double getAverage(int *arr, int size){
int total = 0;
int i;
for(i=0;i<size;i++){
total+=*(arr+i);
}
return total/size;
}
输出结果为:
平均数为300.000000
请按任意键继续. . .
5.8 从函数返回指针
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int * getRandom(){
static int r[10];
int i;
srand( (unsigned)time( NULL ) );
for(i=0;i<10;i++){
r[i] = rand();
printf("随机生成的数[%d]=%d\n",i,r[i]);
}
return r;
}
int main ()
{
int *r;
int i;
r = getRandom();
printf("==================================\n");
for(i=0;i<10;i++){
printf("数组元素值[%d] = %d\n",i,*(r+i));
}
}
输出结果:
随机生成的数[0]=14920
随机生成的数[1]=19019
随机生成的数[2]=8311
随机生成的数[3]=18053
随机生成的数[4]=26906
随机生成的数[5]=22482
随机生成的数[6]=2612
随机生成的数[7]=12707
随机生成的数[8]=4356
随机生成的数[9]=32132
==================================
数组元素值[0] = 14920
数组元素值[1] = 19019
数组元素值[2] = 8311
数组元素值[3] = 18053
数组元素值[4] = 26906
数组元素值[5] = 22482
数组元素值[6] = 2612
数组元素值[7] = 12707
数组元素值[8] = 4356
数组元素值[9] = 32132
请按任意键继续. . .
|