指针:
1、让指针指向一个变量,是一个指针变量保存了一个变量的首地址。
char,int,double
2、 指针和数组明的不同点:
1、sizeof的结果不一样
2、数组名不可修改(数组名是指针常量)
指向一片内存区域,用数组分配这片内存
数组名本身
本身是常量,不可改变,sizeof可以获取整个这片内存的长度(大小)
自定义指针指向一片数组区域
指针是变量,可以改变,sizeof结果为4
注:
int a[10];//a不能改变,a是数组名
int *p = a;
void print(int a[], int n);//a是指针
a++;//a可以改变
sizeof(a) == 4;
a[1] --> *(a+1) //编译过程将被翻译
p[1] --> *(p+1)
3、字符串:
c语言中,字符串的本质是指针。
char str[10]; //str是数组名(常指针)
char *str; //是指针
char str[] = "abcdef" ;
str指针指向了一个栈里面的一个字符串,内容可以修改: strcpy(str, "ABCDEF");
str指针本身是一个常量,不可改变,所以不能:str = "ABCDEF";
char *str = "ABCDEF";
str指针指向了一个代码区中的一个字符串,内容不能修改,所以不可以:strcpy(str, "abcdef");
str指针本身是一个指针变量,可以改变,所以可以使用:str = "abcdef";让str重新指向一个新的字符串。
4
不要用野指针,即使不能初始化一个指针变量,也要将其置为空指针NULL。 NULL是0的宏定义,空指针也可以叫零指针。
悬空指针,尽量避免一个指针指向已经释放的空间,如果指针指向的空间释放了,应该马上让该指针置空,以防止悬空指针的出现。
5
数组指针:
int a[10];
数组名的值是第一个元素(下标0)的地址。
*a 等同于a[0]
&a取到的是整个数组的首地址,取得的值等于a,类型表示为数组指针:int (*pa)[10]=&a;
int a[3][4];
a是一个数组,数组里3个元素,每个元素是int[4]类型的数组。a是第一个元素的地址,a的类型就是(int [3][4] , int (*p)[4]). int (*pa)[4] = a。
6
程序之间数据共享(传递指针参数)
利用二级指针进行指针变量的共享
利用void指针进行通用程序开发
利用函数指针写通用算法
7
指针:
实质上就是地址
内存被分为字节,每个字节有唯一的地址。
指针变量可以存储指针
指针变量的声明:
int *p;int *q; int *k;
int i,j,a[10],*p,*q;
每个指针变量只能指向一种特定类型的对象
8
指针作为参数传递
指针作为返回值:
函数可以返回一个指针
永远不要返回指向自动变量的指针(子函数)。
函数的返回值一般都不会是指针,一般用指针就可以带回想要的值,
而不是返回一个指针。
9
指针的算术运算:(相同类型的运算)
加上整数:向后走多少个数据类型(向高地址走)
减去整数:向前走多少个数据类型(向低地址走)
两个指针相减
指针比较:相同类型才可以比较
用指针处理数组:
*p++ <==> *(p++)
(*p)++
*++p <==> *(++p)
++*p <==> ++(*p)
int *p[4] 指针数组
int (*p)[4] 数组指针(相当于是二维数组)
10
高级指针的应用:
双指针:
指向指针的指针
地址指针,指针的指针,二级指针
想间接的修改指针的指向时,可以使用二级指针
也叫二级指针,用来报存指针变量的地址,为什么用双指针,目的是为了间接地改变一个指针的指向。
双指针,也叫二级指针。用来保存指针变量的地址。为什么用双指针,目的是为了间接地改变一个指针的指向。
void fa(char** str){
*str = "ABCDEF";
}
char* a = "abcdef";
fa(&a);//间接改变了a指针的指向
万能指针(通用指针),void指针:
代表任何类型的指针,对此不能用*取变量,可以用类型转换还原类型。
基本用于函数的参数,在不知道类型时,只要是地址,就可以用void *
万能指针(通用指针) void * void 指针
写一些通用的函数时,不能确定数据类型时,可以用void *接受任何类型的数据。
对一片内存区域进行操作时,直接使用void *(在C里面经常用,但C++不提倡)
函数指针:
指向函数的指针,保存函数首地址的变量
如何声明函数指针变量:
1、写出函数原型
2、将函数名改成变量名,变量名前加*,并用括号括起来,以确保优先级。
函数名本质上就是一个常量指针,保存的就是函数的首地址。
函数指针 = 函数名;
函数指针(实参.. )可以直接调用函数。
保存函数的地址的变量
如何声明函数指针变量:
1、写出函数原型
2、将函数名改成变量名,变量名前加*,并且用()括起来,以确保优先级。
函数名本质就是一个常量指针,保存的就是函数的地址。
函数指针 = 函数名;
函数指针(实参...)可以直接调用函数。
为什么用函数指针:
函数指针的应用比较广泛,函数指针是变量,所以变量能出现的地方,函数指针就可以出现。
比如:可以用数组保存很多函数,可以把函数作为另外一个函数的参数进行传递,用一个函
数返回一个函数。
分析:
void(*signal(int sig,void(*func)(int)))(int);
void(*)(int);
signal(int sig,void(*func)(int))
typedef void(*FUN)(int)
FUN signal(int sig, FUN func);
#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size
,int(*compar)(const void *, const void*));
int a[10] = {};
int compint(const void* a, const void* b){
const int* x = a;
const int* y = b;
return *x - *y;
}
qsort(a, 10, sizeof(int), compint);