指针
1、认识指针
[地址]内存每个直接都有一个唯一编号,称为地址
[指针]存放数据的地址
变量与内存地址的关系
1、变量是在内存中分配
2、变量都有地址
指针变量:用于存放地址的变量
特点:
1、地址是一种特殊的数据类型,所以存放地址的指针变量和存放字符型,整型变量是不同类型的变量。
2、指针变量是一种特殊的变量,他的内容是另一个变量的地址
定义指针
include <stdio.h>
int main ()
{
//定义一个指针变量
//指针是P,int*是类型名(整型指针)
int* p;//整形指针
float* f;//浮点指针
char* c;//字符指针
double* d;//双精度指针
printf("sizeof(int*) = %lu\n", sizeof(int*));
printf("sizeof(float*) = %lu\n", sizeof(float*));
printf("sizeof(char*) = %lu\n", sizeof(char*));
printf("sizeof(double*) = %lu\n", sizeof(double*));
printf("sizeof(long*) = %lu\n", sizeof(long*));
return 0;}
指针变量定义了双类型
1、定义了某个变量本身是指针类型
2、也定义了这个指针变量能够指向变量的类型
在64位系统中,指针类型占8个字节
include <stdio.h>
int main ()
{
//定义一个指针变量
//指针是P,int*是类型名(整型指针)
int* p;//整形指针
float* f;//浮点指针
char* c;//字符指针
double* d;//双精度指针
printf("sizeof(int*) = %lu\n", sizeof(int*));
printf("sizeof(float*) = %lu\n", sizeof(float*));
printf("sizeof(char*) = %lu\n", sizeof(char*));
printf("sizeof(double*) = %lu\n", sizeof(double*));
printf("sizeof(long*) = %lu\n", sizeof(long*));
return 0;
}
如何获得地址:
1、一般变量使用取地址符&
2、数组的首地址可以字节用数组名
指针的初始化
include <stdio.h>
int main ()
{
int num = 0;
//定义整形指针
//int* p;
//1、初始化时让指针指向一个已经存在的变量
//2、
int* p = #
printf("&num = %p\n", &num);
printf("p = 0x%lx\n", p);
return 0;
}
引用所指向的变量
1、格式:*指针变量
2、说明:使用时要注意指针变量必须已经赋值,指向了一个已知的变量
include <stdio.h>
int main ()
{
int num = 3;
int* p = #
printf("pNum = %d\n",*p);
return 0;
}
指针输入
p = #
//scanf("%d", p);
*p = 100;
//修改的时地址位P指向的变量的值
//*p = = = num
为什么要用指针?
指针就是为了跨栈,访问不再当前栈内的数据
[注意]如果想封装一个函数,修改变量的值,形参必须时指向这个变量的指针,实参时这个变量的地址
作业:
编写函数,求三个变量的最大值,求完值之后将三个变量清零
include <stdio.h>
void max(int* a, int* b, int* c);
int main ()
{
int x = 0;
int y = 0;
int z = 0;
scanf("%d%d%d",&x,&y,&z);
int* x1 =&x;
int* y1 =&y;
int* z1 =&z;
max(x1, y1, z1);
printf("x = %d\n",x);
printf("y = %d\n",y);
printf("z = %d\n",z);
return 0;
}
void max(int* a, int* b, int* c)
{
int max = 0;
max = *a;
max = (max > *b ? max : *b) > *c ? (max > *b ? max : *b) : *c;
*a = 0;
*b = 0
*c = 0;
printf("max = %d\n",max);
}
编写函数,修改一个变量,将变量的值改为现有变量的三次方
编写函数,交换两个变量的值。
include <stdio.h>
void change (int* x, int* y);
int main ()
{
int a = 1;
int b = 2;
//(a,b) 值传递
change(&a, &b);//地址传递
printf("a = %d\n",a);
printf("b = %d\n",b);
return 0;
}
void chang(int* x, int* y)
{
int s = 0;
s = *x;
*x = *y;
*y = s;
}
指针变量指向数组的方法
1、指针指向数组的首地址
1)用赋初值方法
*指针变量 = 数组名 ;
2)在程序中赋值
指针变量 = 数组名;
{
int* p = NULL;
int a[10] = 0;
……
p = a;
}
指向数组的某个元素
1)用赋初值方法
* 指针变量 = &数组名[下标]
2)在程序中赋值
指针变量 = &数组名[下标]
指向一位数组的指针的使用
1、当指针变量指向了数组的首地址
引用数组元素[i ]:*(指针变量+i)
include <stdio.h>
int main ()
{
int num[5] = {1,2,3,4,5};
int*p = num;
printf("*p = %d\n", *p);
printf("*p+2 = %d\n", *(p+2));
return 0;
}
2、当指针指向下标为I的数组元素
引用数组元素(i:*(指针变量+1)
引用数组元素(i+k)*(指针变量+k)
引用数组[i-k]:*(指针变量-k)
指针🆚下标
下标运算比较直观,下标运算只能做绝对运算
指针运算非常灵活,指针运算可以做相对运算
指针引用和下标引用数组元素的实质时相同的
1)8(指针变量+i)
2)*(数据数组+1)
3 指针变量[i]
4 指针变量名[]
计算机并不知道数组有多长。只知道数组元素的首地址
指针变量的指针自减
++ ,--
指针变量++
++指针变量
指针变量--
--指针变量
include <stdio.h>
int main ()
{
char chr[5] = {'q','w','e','r','t'};
char* p = chr;
printf("*p = %c\n", *p);
p++;
printf("*p = %c\n", *p);
++p;
printf("*p = %c\n", *p);
--p;
printf("*p = %c\n", *p);
return 0;
}
指针变量减指针变量
[注意]要求这两个指针必须指向同一个数组。否则不能运行减法运算
,运算的结果是,他们所指向数组元素下标的差
编写函数,将任意长度的整形数组逆序(从终端接受)
void func( int* a ,int n)
include <stdio.h>
include <string.h>
void func(char* a, int n);
int main ()
{
char chr[128] = "";
gets(chr);
func(chr, strlen(chr));
printf("%s\n",chr);
return 0;
}
void func(char* a,int n)
{
char chr1 = '\0';
for(int loop = 0;loop < (n/2);loop++)
{
chr1 = a[loop];
a[loop] = a[n - 1 - loop];
a[n - 1 - loop ] = chr1;
}
return;
}
指针和字符串
将指针变量指向字符串常量 “hello”
1)用赋初值的方式
例如:char* p = “hello”;
- 先定义,再赋值
例如:char* p ;
p = “hello”;
include <stdio.h>
void func(char * t);
int main ()
{
char* p = "hello";
func(p);
return 0;
}
void func(char* t)
{
printf("t = %s\n",t);
*t = 'H';
return;
}
泛型指针
void* p;可以存储任何变量的地址,没有类型的限制,也可以和任何类型的指针进行赋值
[注意]泛型指针不能加减,不能取*;
//将void*强制转换为char*
char* m = (char*)t;
野指针
如果一个指针没有初始化,只能认为这个指针指向了不能预测的地方,称为野指针。如果使用了野指针,将会造成不可预知 的错误❌,因此将不能及时初始化的指针赋值为NULL,如果没有一个明确的赋值,就用了指针,程序会崩溃
网友评论