1.指针类型
C语言指出,一个变量的首地址称为该变量的指针。记作&x
如 int *p;
我们一般说p指向int类型
2.指针变量
指针变量是用来存放变量首地址的变量
int* p;
p就是指针变量.
指针变量的访问
直接访问:
int a=3;
*(&a)=3;
都是合法的。
间接访问:
p=&a;
*p=3;
比较 int *p
int a,除了*p多一个*之外和a相同。如果把*p=&a,初始化成功。那么*p就可以和a一样访问a的变量值了。
指针变量本身也占用内存单元,所有类型的指针变量占用字节数都是一样的。
指针类型决定指针变量解引用时,能够访问空间的大小。
例如int a=0x00112233 char *p=&a;*p=0
输出a=0x00112200,改一个字节。
int *p=&a;*p=0;
输出a=0x00000000;改四个字节
指针类型决定了指针走多远。
int *a;a+1->4
char*a;a+1->1
double*a;a+1->8
野指针:
指向的位置是不可知的(随机的,不正确的,没有明确限制的)。
#include<stdio.h>
void main()
{
int arr[] = {1,2,3,4,5,6};
int zf = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;
for (i = 0; i < zf; i++)
{
printf("%2d",*p);
p++;
}
}
#include<stdio.h>
void main()
{
int a = 256;
char* pa = &a;
*pa = 5;
printf("%d",a);
}
256用二进制表示为100000000,而char*是改变一个字节,也就是八个二进制位。*pa=5;那么a=100000101,a=261。
那么问题来了,为什么我们确定取出来的是最低位1个字节?这跟我们电脑的字节序有关,有的电脑是大端存储,有的是小端存储。大端存储是高位存低地址,低位存高地址。而小端则是低位存低地址,高位存高地址。巧记:大变小不变。
#include<stdio.h>
int sys()
{
int a = 1;
return *((char*)&a);//取a的地址,强制转化成char*类型,取一个字节
//然后结果为1则是小端
}
void main()
{
int ret=sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
}
例:通过指针操作字符串。
#include<stdio.h>
#include<string.h>
void main()
{
char* pa1,*pa2;
char a[] = "I love you";
pa2 = &a[0];
while(*pa2!= '\0') putchar(*pa2++);
putchar('\n');
while (--pa2 >= &a[0]) putchar(*pa2);
}
先将字符串正向打印,然后再反向打印。
这里*和++是相同优先级,但是C语言讲究操作运算符结合方向为自右向左。*pa2++等价于*(pa++),同理*--pa
void main()
{
int a[2][3] = { {1,2,3},{4,5,6} };
int* p;
for (p = a[0]; p < a[0] + 6; p++)
{
if ((p-a[0])% 3 == 0)
printf("\n");
printf("%4d",*p);
}
}
#include<stdio.h>
#include<string.h>
void main()
{
int a[] = {1,2,3,4};
int b[] = {2,3,4,5};
int c[] = {4,5,6,7};
int* arr[3] = {a,b,c};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%2d", arr[i][j]);
}
printf("\n");
}
}
指针数组可以将几个不相关的数组联系起来。达到二维数组的效果。
进阶:
#include<stdio.h>
void main()
{
char a[] = "I love you";
printf("%s\n", a);
}
这里输出了字符串。为什么呢?
上面我们不是讲数组名存的是首元素地址吗?那么应该输出的是I 才对啊?
其实是因为%s搞的鬼。%s是输出字符串,而且遇到/0才结束,才会输出整个字符串。