C语言ggg是什么函数指针,第5天 函数 模块 指针.md

本文讲解了C语言中return与exit的区别,介绍了如何通过''计算字符串长度,探讨了函数声明与定义的技巧,以及模块编程的分文件实现方式,包括简单分文件、头文件使用和防止头文件包含多次的方法。此外,还解析了指针的基础概念、野指针和空指针,以及多级指针和数组名指针的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[TOC]

#### 1.) return和exit的区别:

return是中断(结束)函数,void不需要return.

exit是中断整个程序的,exit需要stdlib.h头文件

#### 2.) 测试题:手动计算字符串长度:

利用结束符: '\0'

```

#include

int len(char str[]) {

int i =0;

while(str[i] != '\0') {

i++;

}

return i;

}

int main(){

char str[] = "woshi";

int i;

i = len(str);

printf("%d",i);

return 0;

}

```

#### 3.) 函数的声明和定义

声明和python一样,必须在调用之前就声明,

也就是说函数在main中调用的话,必须在main前声明

定义可以延后。

声明函数(定义延后):告诉编译器这个函数是有定义的,只是放在其他地方。

声明的形参和定义的时候的形参可以不一样。

```

#include

void func2()//提前声明fun2(),以供调用

void func1(){//这里声明了func1(),故在main()中可直接调用

printf("http://c.biancheng.net");

//也可以在这一行进行fun2()的声明,只要是在func2()之前就可以

func2();

}

void func2(){

printf("C语言小白变怪兽");

}

int main(){

func1();

return 0;

}

```

#### 4.) 模块编程

分文件的形式:

一般按功能分

##### 1. 简单分文件

比方说在b.c中写len函数,也可以定义为头文件,b.h

```

int len(char str[]) {

int i =0;

while(str[i] != '\0') {

i++;

}

return i;

}

```

而a.c,引入b.c

```

#include

#include "b.c"

int main(){

char str[] = "woshi";

int i;

i = len(str);

printf("%d",i);

return 0;

}

```

##### 2. 头文件只声明

https://blog.csdn.net/aiwoziji13/article/details/7330333

一般的做法:

把函数声明放在头文件中,函数定义放在另一文件中

而在主函数的文件中,只需要引入头文件就行。

len.c

```

int len(char str[]) {

int i =0;

while(str[i] != '\0') {

i++;

}

return i;

}

```

all.h

```

int len(char str[]);

```

main.c

```

#include

#include "c.h"

int main(){

char str[] = "woshi";

int i;

i = len(str);

printf("%d",i);

return 0;

}

```

##### 3.同一文件防止头文件包含多次,只有一次生效

```

main.h第一行写:推荐这种

#pragma once

```

或者len.h中写

```

ifndef _MYSTRLEN_H

#define

extern int my_strlen(char buf[]);

#endif

```

#### 5.) 指针的定义和使用

指针也是一个类型: int * 变量名;

int *表示该指针一次操作的内存空间是int长度。

int * p;//p的类型是int *

printf("%p",p);

##### 1.指针指向谁,就保存其地址。%p是以16进制打印。

*p取内容

```

#include

int main(){

int a=234;

int * p;

p = &a;

printf("%p,%p\n",p,&a);

printf("%d",*p);//234

}

```

##### 2.对*p赋值会直接改变所指的变量值

#### 6.野指针

这个指针变量保存了一个非法的地址。

只有定义后的变量,此变量的地址才是合法地址。

换句话说,只有系统分配的地址才是合法地址。

```

#include

int main(){

int *p;

p =0x1234;

printf("%d",*p);//这里可以运行。

*p =100;//这里就是非法的,程序报错终止。

}

```

另一种情况

```

int a =10;

int *p;

*p = &a; //赋值错误,应该p=&a;操作野指针的报错。

int b = *p;

```

#### 7.空指针,稍微防止野指针。

```

int *p = NULL;

if(p !=NULL) {

//做操作

}

```

#### 8.指针大小

32位编译器用32位保存地址

64位编译器用64位保存地址

使用sizeof查看下。

#### 9.多级指针

如果定义一个合适类型的变量保存另一个变量的地址

在需要保存变量地址的类型基础上加一个*

```

int a = 10;

int *p = &a;

int **q = &p;

int ***t = &q;

```

#### 10. []的使用

*p等同p[0]

```

#include

int main(){

int a;

int *p = &a;

p[0] = 100;//等价于*p =100;

//这里p[1]就是野指针了。

printf("%d",a);

}

```

#### 11.万能指针和指针步长

##### 1. 万能指针

我们不能定义void的普通变量(因为编译器不知道该分配多少内存空间

但是能够定义void *p,因为大小确定。32位系统分配32位,64同理。

```

void *p =NULL;

int a = 10;

p =&a;

* ((int *)p) = 200; //为什么需要转换,这是告诉编译器该指针要操作多少的内存空间。

```

##### 2.步长

int *p; 一步是int(一般4字节)

指针的步长是由指向的变量的类型决定的。

```

#include

int main(){

int a;

int *p = &a;

printf("%p,%p",p,p+1);//0061FEC8,0061FECC ,单位字节。

}

```

#### 12.) const修改符的指针变量

const 修改的是 *。

```

int a=100;

//指针所指向的内存是只对的。

const int * p = &a;

//等同int const *p =&a;

```

但是如果这样:

```

int * const p = &a; 表示修饰的变量p不能改变。

```

#### 13.) 数组名

数组名是数组首元素地址

int a[]={1,2,3};

a等同a[0];

a不能修改,类似int * const p;

#### 14.指向数组首元素的指针

```

#include

int main(){

int a[] = {1,2,3};

int *p = NULL;

p = &a[0]; //等价p = a;

printf("%d\n",p[2]);//3

printf("%d\n",*(p+1));//2

}

```

一键复制

编辑

Web IDE

原始数据

按行查看

历史

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值