定义:系统在编译代码时会给变量分配内存地址,此地址称为变量的“地址”,指针是一个存储地址的一个变量,称为指针变量。指针变量中的地址是可以被改变的。
指针的定义
类型名 * 指针变量名
int* p; //指向整型的指针
char* p1; //指向字符型的指针
double* p2;
int** p3; //指向指针地址的指针。
注意:注意指针类型和指针指向的类型。例如int* p,指针类型为int* ,是指向int类型的指针
int**p3 是指针类型改为int**,是指向int*的指针。指针的大小为4字节。
运算符&和* 和指针的运算
& 取地址运算符
* 解引用,指向地址里的值
int a = 0;
char arr[] = "abcdef";
char s;
int* p; //整形指针p
char* p1 = &s; //字符指针p1
char* p2 = arr; //字符指针p2
p = &a;
*p = 20;
s = 'a';
*p1 = s;
printf("%d,", *p);
printf("%d", a);
printf("%c %c", s, *p1);
printf("%s %s",arr,p2);
指针可以加或者减去某个数,表示指向地址向前或向后移动n个类型大小的位置,可以叫做指针的偏移。
int array[20]={0};
int *ptr=array;
for(i=0;i<20;i++)
{
(*ptr)++;
ptr++;
}
指针作为函数传递
函数参数传递中有传值和传址两种方式
通过值传递方式传递后作为形参,形参的值改变不会对实参的值有影响。通过传址的方式,改变形参的值,形参也会随之改变。
void swap(int* x, int* y)
{
int temp = 0;
temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a = 123, b = 456;
swap(&a, &b);
system("pause");
return 0;
}
1.指针数组 //存放指针的数组
int arr1[] = {1,2,3};
int arr2[] = {4,5,6};
int arr3[] = {7,8,9};
int* arr[] = {arr1, arr2, arr3};
2.数组指针
变量是有地址,相应的数组也有地址.数组指针就是指向数组的指针。
int arr[10] = 0;
int *p = arr;
int (*p)[10] = &arr; //数组指针
注意:arr 和 &arr[0]为数组的首元素地址 ;&arr为数组的地址。
数组指针指向的是数组的首地址 等价于 p = &arr[0];下面三种方式都可以输出数组array。
#include<stdio.h>
//一维数组传参
//void ptint(int arr[])
void print(int* arr) //和上面等价
{
for (int i = 0; i < 10; i++)
{
//三种方式等价
//printf("%d", array[i]);
printf("%d ", arr[i]);
printf("%d ", *(arr+1));
}
}
//二维数组传参
//void print1(int arr[][3],int x,int y);
void print1(int (*p)[3],int x,int y);
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%d ", p[i][j]);
printf("%d ", *(*(p+i)+j));
//printf("%d ", (*(p+i))[j]);
}
}
}
int main()
{
int array[10] = {0,1,2,3,4,5,6,7,8,9 };
inte arr[][] = {{2,3,4},{4,5,6},{7,8,9}};
int* ptr = array;
for (int i = 0; i < 10; i++)
{
//printf("%d", array[i]);
printf("%d ", ptr[i]);//和上面等价
}
print(array);
print1(arr,3,3);
return 0;
}
二维指针传参时。行可以省略,列不能省略。
结构体指针·:指向结构体变量的指针
void my_qusort(struct student* std, int num, int L, int H);
struct student
{
char xuehao[8];
int d_fen;
int c_fen;
};
int main()
{
int s_num = 0, L_line = 0, H_line = 0;
struct student std[1000] = {0};
//输入学生数量,最低录取线,优先录取线
scanf("%d %d %d", &s_num, &L_line, &H_line);
//输入N个学生的学号,德分,才分
for (int i = 0; i < s_num; i++)
{
scanf("%s %d %d", &std[i].xuehao, &std[i].d_fen, &std[i].c_fen);
}
my_qusort(std,s_num,L_line,H_line);
return 0;
}
void my_qusort(struct student* std, int num,int L,int H)
{
if (std->d_fen >= L && std->c_fen >= L)
}
函数指针 :指向函数的指针
函数指针数组:
int Add(int a,int b)
{
return a+b;
}
int Sub(int a,int b)
{
return a-b;
}
int Mul(int a,int b)
{
return a*b;
}
int Div(int a,int b)
{
return a+b;
}
int main()
{
int a = 0, b = 0;
int (*p)(int, int) = Add;
int (*p[4])(int,int) = {Add,Sud,Mul,Div};
printf("%d" , (*p)(2,3));
return 0;
}
void ( *singel(int, void(*)(int)) )(int)
c动态内存分配
动态内存分配是使用户可以根据自己的需要,向系统申请所需大小的内存空间;需要包含<stdlib.h>头文件。
相关函数介绍
1、molloc函数: molloc(int size);
用于分配一个大小为size的内存区域。默认开辟类型为void,不会初始化
int * p = NULL;
p = (int*)malloc(4);
*p = 100;
free(p);
2、calloc函数: calloc(unsigned n, int size);
用于分配n个大小为size的连续内存,可以为一维数组开辟动态内存空间。//默认初始化赋值为0
int *q = (int*)calloc(10,sizeof(int));
3、realloc函数:realloc(void * p, unsigned int size);
用于改变已经通过malloc函数或者calloc函数开辟的内存空间的大小。
realloc(q,11*sizeof(int));
4、free函数:void free(void * p);
用于释放指针变量所指向的动态内存空间。