什么是指针数组
指针就就是数据的内存地址。函数
指针的做用一指针
当你须要在函数间传递大量数据时就用指针,由于能够下降的内存开销内存
指针的做用二字符串
定义指针变量的格式it
定义一个指针变量的方法编译
Examples:ast
char *p;变量
int *q;软件
float *r;
long double *s;
long int *t;
没有初始化的指针
没有初始化的指针
1.没有初始化的指针,称之为野指针。
2.指针里面是一个随机的值。
3.野指针有很大的风险。
如何初始化一个指针?
Answer: set it to NULL
int *p;
p = NULL;
或者
p = 0;
注意:永远不要使用一个空指针。
在C里,使用空指针会有一个空指针错误。会使得程序崩溃。
如何初始化一个指针?
int a;
int *p;
p = &a;
代码演示
*pr = *pa + *pb;
如何经过指针去访问一个变量
For example:
p = &a;
c = *p + 43;
指针访问内存能够经过*这个操做符去访问所指向的内存空间。
特别注意:
1.永远不要返回一个指向本地变量的指针。
Why?
float *mistake()
{
float temp = 12;
return &temp;
}
指针变量所占用的存储空间
为什么指针变量要分类型?
int i = 2;
char c = 1;
int *p = &c;
printf(“%d”, *p);
指针与数组
数组名就像是一个指针
char name[] = {‘i’,’t’,’c’,’a’,’s’,’t’};
char *np = name;
那么
name[1] == *(name +1) == *(1 + name) == 1[name]==*(np + 1) == *(1 + np) == *(np++) == np[1] == 1[np]
为何数组下标是从0开始的?
数组是一块连续的内存
数组元素的下标是,是该元素的位置相对与数组起始地址的偏移量
由于第一个元素的地址与数组名地址是相同的,因此偏移量是0
数组名与指针的区别
char array [] = {‘i’,’t’,’c’,’a’,’s’,’t’};
char *p = array;
sizeof(array) 返回的结果是array所占的字节数,sizeof(p) 是 8
当使用指针变量指向一个数组的时候,数组有些信息不能经过指针,好比数组长度,这称为指针信息遗失。
&array = array,&p != p
数组的地址仍是数组的地址,指针的地址变量的地址不是指针变量里存放的地址
数组变量的指向不能够改变
指针变量就是就是用来存放地址变量,系统为其开辟了存储空间,因此指针变量中地址能够任意改变,可是系统没有数组变量分配存储空间,当系统编译后全部出现数组名的地方都会被替换成该数组的首地址,因此你不可该数组变量的指向。
字符串的两种表示方式
字符数组
char name[] = “itcast” ;
字符指针
char *name = “otcast”;
二者区别
使用字符数组定义的字符串,系统会把字符串中的每一个字符拷贝到字符数组中;所以你能够变字符串中的字符
使用指针定义的字符串,系统把常量字符串的地址赋值给了char类型的指针。因此你不能经过指针改变字符串中的字符,由于字符指针指向的字符串是一个常量,是只读的。
系统内存分区
两种字符串的区别
使用数组定义的字符串
该字符串存放在栈中
你能够随意的修改字符串中的字符
当你返回一个函数内部定义的字符数组时候,它返回的是这个数组的地址,你若在外边使用这个地址会报错,由于该变量在函数执行完成后比回收了。
使用字符指针定义的字符串
该字符串存放在常量区
你不可修改该字符串中的字符,由于它是只读的
你可使用它做为函数的返回值,它返回的是常量的地址,由于常量是常驻内存,直到程序退出才会被回收,因此你能够放心使用不会报错!
指针数组与指向数组的指针
指针数组就是数组元素为指针的数组
定义一个指针数组格式:数据类型 * 指针数组名[元素个数]
如:int a[2][2] ={1,2,3,4}
int *ap[2] = {a[0],a[1]}
指向数组的指针就是一个指针变量,它是用来指向数组的也能够说,它指向数据类型是数组
定义一个指向一维数组的指针
格式:数据类型 (*指针名称)[指向的一位数组的元素个数]
如 int a[2][2] = {1,2,3,4}
int (*p)[2] = a;
注意:括号不能够省略
指针与字符串数组
定义指针数组的两种形式
char *name[]={"Monday", "Tuesday”}
char name[][8]={"Monday", "Tuesday”}
这两种形式的区别是什么呢?
指向指针的指针
所谓的指向指针的指针就是:这个指针变量中存放的地址是一个指针变量的地址;如:
int a = 10;
int *p = &a;
int **pp = &p;
咱们要访问a中的值该怎么办呢?
*p 能够访问 a 的存储空间,操做a变量中的值
*pp能够访问 p 拿到 p中存放的地址因此
**pp能够访问p所指向的存储
指向指针的指针使用场景
定义一个把字符串的内容写到文件中的函数
方式一 :
char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"};
char **p;
p = name;
p = name + 1;
使用方式二:在函数中返回一个常量字符串的地址
int writeToFile(char *conttent,char **error){
// 检查文件是否被锁定了
if(isLocked){
*error = “该文件没法写入,它被其余软件占用了”;
return 0;
}
//写文件
}
什么是函数指针
指向函数的指针称为函数指针,也就存放函数地址的变量就是函数指针变量
函数指针定义的格式
格式:
返回值类型 (*函数指针名称) (参数类型,参数类型)
定义一个指向 int sum (int a,int b); 函数指针的步骤
首先是指针相关必就有 *
是变量就有名字 *myPoint
将要指向的函数的名左边拷贝到左边 int *myPoint
将要执行的函数的名右边拷贝的右边 int *myPoint (int a,int b)
因为*的优先级低于()的优先级,如今这个是返回值为int * 的函数
咱们须要给 *myPoint加上括号来提升它的优先级 int (*myPoint) (int a,int b)
(可选)函数指针能够省略形参名称 int (*myPoint) (int ,int )
函数指针初始化
函数名就是函数的地址,而函数指针变量就是存放函数地址的,因此能够直接把函数名赋值给函数指针
先定义在初始化
int (myPointer)(int,int);
myPointer = sum;
定义的同时进行初始化
int (myPointer) (int,int) = sum;
如何使用函数指针
因为函数指针存放就是函数的地址,函数名也是函数地址,因此能够像函数名同样使用函数指针
int s = myPointer(10,20);
你也找到函数对应的代码来执行它,这种方式不经常使用
(*myPointer)(10,20);