嵌入式学习--C语言Day07
指针修饰
const
常量化 只读
const修饰普通变量
不能直接通过变量名进行赋值修改,可通过指针间接修改
const int a = 777;
int *p = &a;
//a+=5; //错误
*p+=5;
printf("%d\n",a);//782
const修饰指针
const int *p
int const *p
const修饰指针指向内容,指向的内容不能被修改,可以修改指针的指向
int a = 777;
const int *p = &a;
//*p = 999; //错误
int b =999;
p = &b;
printf("%d\n",*p);//999
int * const p
const修饰指针的指向,指向不能被修改,可以修改指向的内容
int * const p = &a;
int b =999;
//p =&b; //错误
*p = 999;
printf("%d\n",a);//999
int const * const p
const既修饰指针的指向,又修饰指针指向内容
void
修饰指针,函数
不能修饰变量
void *p = NULL; //void 任意类型指针;后期使用需要强制转换
void *p=NULL;
char a = 'q';
p = &a;
printf("%c\n",*(char*)p);
大小端
小端:低地址存放低字节数据
大端:低地址存放高字节数据
0x12345678
大端:12 34 56 78
小端:78 56 34 12
int a = 0x12345678;
char b = (char)a;
printf("%#x\n",b);
二级指针
一级指针存放普通变量的地址
二级指针存放一级指针的地址
格式
存储类型 数据类型 **指针变量名
int **p
int a = 4;
int *p = &a;
int **q = &p;
普通变量a的地址:&a p *q
普通变量a的值: a *p **q
一级指针的地址 &p *q
q == &p q &p
*q==*&p == p ==&a *q p &a
**q ==*p ==*&a ==a **q *p a
指针和数组
直接访问:通过数组名进行访问
间接访问:通过指针进行访问
直接访问
int a[5] = {5,6,7,8,9};
一维数组的数组名也是数组的首地址
地址 | 元素 | |||
a | &a[0] | 5 | a[0] | *a |
a+1 | &a[1] | 6 | a[1] | *(a+1) |
a+2 | &a[2] | 7 | a[2] | *(a+2) |
a+3 | &a[3] | 8 | a[3] | *(a+3) |
a+4 | &a[4] | 9 | a[4] | *(a+4) |
间接访问
地址 | 元素 | |||
p | &p[0] | 5 | p[0] | *p |
p+1 | &p[1] | 6 | p[1] | *(p+1) |
p+2 | &p[2] | 7 | p[2] | *(p+2) |
p+3 | &p[3] | 8 | p[3] | *(p+3) |
p+4 | &p[4] | 9 | p[4] | *(p+4) |
a和p是否完全一样?
不是,a是数组名,是地址常量,不能为左值
p是指针变量,可以被修改;
运算方法
int a[] = {5,16,27,38,49};
int *p =a;
*和++都是单目运算符
单目运算符优先级相同,从右向左运算
*p++ 先算p++,由于++在后,对p加*取内容,然后p+1
*(p++) 同上
*++p 先算++p,由于++在前,先算p+1,然后对p加*取内容
*(++p) 同上
(*p)++ 先对p加*取内容,对内容++,由于++在后,先打印,然后*p+1
++*p 先对p加*取内容,对内容++,由于++在前,先算*p+1,然后打印
int x[5] = {10, 20, 30};
int *px = x;
printf("%d,", ++*px); //11
printf("%d\n", *px); //11
px = x; //{11,20,30}
printf("%d,", (*px)++); //11
printf("%d\n", *px); //12
px = x+1; //{12,20,30}
printf("%d,", *px++); //20
printf("%d\n", *px); //30
px = x+1; //{12,20,30}
printf("%d,", *++px); //30
printf("%d\n", *px); //30
补充:
char a[33]="hello";
//在栈区空间开辟33字节,存储"hello"
char *p="hello";
//"hello"存储在常量区;p在栈区,存储字符串所在常量区的首地址;
//p只能读取内容
char *p = "hello";
char *q = "hello";//常量区hello的首地址
if (p == q)
printf("qqq\n");
char a1[33] = "hello";//栈区新开辟33的空间存储hello
char a2[33] = "hello";//栈区新开辟33的空间存储hello
if (a1 == a2)
printf("aaa\n");
指针和二维数组
直接访问
int a[2][3] = {2,3,4,5,6,7};
//数组名是行地址,一行里边有多列,行>列,如果想访问到列,需要加*降级处理
// *a第一行第一列
//*a+1第一行第二列
//*(a+1)第二行第一列
//*(a+1)+1第二行第二列
// a第一行首地址
//a+1第二行首地址
//a[0]第一行第一列
//a[0]+1第一行第二列
地址 | 元素 | ||||||
*a | a[0] | a | &a[0][0] | 2 | a[0][0] | *a[0] | **a |
*a+1 | a[0]+1 | &a[0][1] | 3 | a[0][1] | *(a[0]+1) | *(*a+1) | |
*a+2 | a[0]+2 | &a[0][2] | 4 | a[0][2] | *(a[0]+2) | *(*a+2) | |
*(a+1) | a[1] | a+1 | &a[1][0] | 5 | a[1][0] | *a[1] | **(a+1) |
*(a+1)+1 | a[1]+1 | &a[1][1] | 6 | a[1][1] | *(a[1]+1) | *(*(a+1)+1) | |
*(a+1)+2 | a[1]+2 | &a[1][2] | 7 | a[1][2] | *(a[1]+2) | *(*(a+1)+2) |
间接访问
int a[2][3]={2,3,4,5,6,7};
int *p=a;
printf("%p %p\n",a,a+1);
printf("%p %p\n",p,p+1);
//p是普通的指针变量;普通的指针变量无法灵活访问数组
指针数组
数组指针