1.1 函数
实现功能的模块
int add(int a,int b)
形参: 自定义函数内部,存放栈中,,自定义函数结束后被释放
实参:main 函数中需要给函数赋值,局部变量,存放再栈中
局部变量: 全局变量
函数的声明:
当自定义函数处在main函数下的时候,
需要进行函数的声明(返回值 参数名)
1.2 指针 通过直接间接操作值
内存由字节组成,地址就是指针
p指针 *p取值
int a = 10;
int *p = &a;
p = &a;
*p = a;
p的数据类型 int *
p指向的数据类型是int型
指针的数据类型大小在32os是4个字节,不会因为指向的数据类型er
发生改变
int * char * double * float * 都是四个字节
*&a &a先取出a的地址 在取a的值 *于&在同一侧相互抵消
*p = 20 间接的操作一个空间
通过改变 *p 进而改变p指向空间里面内容
%p 打印指针的地址十六进制方式输出指针附加0x和%x完全不同
int a = 10, b = 20;
p = &a;
*p = b ;//只能通过*p改变a的值,间接改变a的值
空指针和野指针
野指针:没有固定指向的指针,不知道指向那片空间;// int * p;
可以使用野指针指向 NULL;
int *p = NULL;
const:
const int *p;//修饰的*p整体不能改变,和p没有关系p可以改变
int const *p;// 修饰的*p整体不能改变,和p没有关系p可以改变
int * const p;//修饰的p,p不可以改变,*p可以改变
const int const *p;//*p不能改变 和p没有关系,p可以改变
int const * const p:p和*p都不能被改变
const 在那个地方,在*左边,*p不能改变 *右边 p不能被改变
1.3指针和一维数组:
int arr[5] = {1,2,3,4,5};
arr这片空间名字,这片空间的首地址 &arr[0] = arr;
int *p = arr;
*(arr+i); arr+i可以进行数组的输入、输出但是 arr++不行 arr为整数
p[i]=arr[i];
*(p+i)//输出
scanf(“%d”,p+i); scanf(“%d”,&p[i])//输入
经过scanf之后p已经指向了第5个元素,所以p=arr回到第一个元素(需要对p进行重置)
2.1 指针的运算
int *p = arr; int *p = &arr[0];
arr = &arr[0]
数组名的输入输出
&arr[i] arr[i]
arr+i *(arr+i)
指针输入输出
&p[i] p[i]
p+i *(p+i)
p++ *(p++)
q和p中间差一个自动计算(减出来的字节数除以sizeof())
p++;往地址增大的地方,移动一个数据类型的大小p的指向发生改变
p+1:往地址增大的地方,移动一个数据类型的大小 p的指向没有发生改变
p--:往地址减小的地方移动,p的指向发生改变 p= p -1
p-1:往地址减小的地方移动,p的指向没有发生改变
2.2 指针和一维字符数组
字符串,用数组名输出的时候相当于a的地址输出 但abcde是一个串
Char str[10];str[10] =”abcde”;错没有字符数组最大到9没有10
Char str[10];str=’’abcde”;错 str是指针常量不能给常量赋值
Char *s; *s=“abcde”;错 *s为字符型只能赋一个值 *s野指针 0号地址不能拿来使用,抢占内存空造成段错误 非法操作零号地址
Char *s=NULL;s=”abcde”;可以,先让指针指向零号地址,当需要被指向的字符串出现时让指针指向字符串
char *s =”abcde”, *s=”ab”;错误 常量不能被改变
char *s=”abce,s=”ab” 改变指针的指向
char str[10]=“abcd”;char *p, p =str; 可以
char str[10]= “abcde”,*p = str; p =&str[2] ; 可以
char *s=”abcde”,s++;printf(“%s”,s);bcde
封装strlen
int my_strln(int *p)
{
int i = 0;
while(*(p++) != ‘\0’)
{
i++;
}
return i;
}
2.3 二级指针
一级指针存放普通变量的地址,二级地址存放的是一级指针的地址
p本身的的数据类型是int * 指向数据类型 int
数据类型比指向的数据类型多一个*
二级指针的数据类型
数据类型: int **
类型: int *
int **p=&q
*q = p = &a *q间接得到a的地址 **q = *p = a
通过二级指针的指向可以间接改变一级指针的指向 *s = &b; s = &p
2.4 const修饰二级指针
int const **p:不能改变 **p
int ** const p:不能改变 p
2.5 指针数组
本质是一个数组,不过里面都是指针
int a =10,b = 20,c = 30;
int *arr[3] = {&a,&b,&c};
strlen strcat strcpy strcmp
strcpy:
strcat:
strcmp:
空格为32 char a=’ ‘;
char *s;
s = “abcde”;对
s = {“abcde”};错 expect expresion before “{“ token s先取搞{
改 s= “{\”abcde\”}”; \转译字符
数组指针
指向的是数组的整体,也是一维数组
int (*p)[5] = &arr; p = &arr; *p = arr;
1.1数组指针和二维数组
二维数组的本质: 数组元素是一维数组的一维数组
int arrary[3][4] int (*p)[4]
int array[3] int(*p)[3] = a
&a = a = &a[0]
&a[0][0] a[0] &a[0] a &a p
1.2 数组指针元素的输入输出
int (*p)[4]= arr;
p = arr;
arr[i][j]
*(arr[i]+j);
*(*(arr +i) +j)
一维
int (*p)[4] = &array
地址表 输出表
&(*p)[i] (*p)[i]
(*p)+i *(*p+i)
二维
地址表 输出表
&p[i][j] p[i][j]
p[i]+j *(p[i]+j)
*(p+i)+j *(*(p+i)+j)
1.3 malloc 和 free
void *str 万能指针 可以代替 int * char * double *
查看函数 man 3 malloc
malloc 动态内存分配
void *malloc(size_t_size)
作用在堆中申请一片空间
#inlcude <stdlib.h> 头文件
返回值:成功返回申请空间首地址,返回失败NULL
参数:想要申请多大空间sizeof()计算
void free(void *ptr)
作用:释放申请空间
参数: 申请空间首地址
void *memset(void *s,int c, size_t n)
#include <string.h>
作用:清空申请空间
参数1:申请空间的首地址
参数2:用什么数据去清空
参数3:清空多大空间
void * 万能指针不知道分配多大内存空间