C语言再学习8-指针(x86)

指针的定义

当我们定义传统类型的时候

int a;
short b;
char c;

我们在任何使用的类型名字上面加上星号*就会产生新的类型

int* a;
short* b;
char* c;
int***** a;
short*** b;
float********** d;
My* m;//自定义结构体
...
  1. 带有的变量类型的标准写法:变量类型 变量名
  2. 任何类型都可以带* 加上*以后是新的类型
  3. *可以是任意多个


回顾传统的定义变量的时候

int a;
a=1;
char b;
b=2;

实际上这是一种精简写法


指针的宽度




a=(int)10;
b=(char)20;

int* a;

当我们使用int*的时候,数据的宽度是多少?

char* a=0;
short** b=0;
int*** c=0;
double***** d=0;
My* m = {0};

我们声明了char*,short**,int***等等。。

	char* a=0;
00E01E78 C7 45 F8 00 00 00 00 mov         dword ptr [a],0  
	short** b=0;
00E01E7F C7 45 EC 00 00 00 00 mov         dword ptr [b],0  
	int*** c=0;
00E01E86 C7 45 E0 00 00 00 00 mov         dword ptr [c],0  
	double***** d=0;
00E01E8D C7 45 D4 00 00 00 00 mov         dword ptr [d],0  
	My* m = {0};
00E01E94 C7 45 C8 00 00 00 00 mov         dword ptr [m],0 

宽度始终为4字节;dword;

  1. 带*类型的变量赋值时只能使用“完整写法”
  2. 带*类型的变量宽度永远是4字节、无论类型是什么,无论有几个 *


指针加加

a++; b++; c++;
printf("%d,%d,%d", (int)a, (int)b, (int)c);

输出的结果
在这里插入图片描述

再次测试

int a = 0;
int* a1 = 0;
int** a2 = 0;

char b = 0;
char* b1 = 0;
char** b2 = 0;

short c = 0;
short* c1 = 0;
short** c2 = 0;

a++; a1++; a2++;
b++; b1++; b2++;
c++; c1++; c2++;

printf("%d,%d,%d\n%d,%d,%d\n%d,%d,%d", a,(int)a1,(int)a2,b,(int)b1,(int)b2 , c, (int)c1, (int)c2);

在这里插入图片描述

当int a或者是short a或者是char a的时候,每次加加都会让里面的值加加,从0变成1
当int的时候,每次加加的宽度是int,int a1=0;a1++,a1的值是0,但是a1加加以后是4

结论:
当我们使用int*进行加加的时候,我们每次加加的宽度为int(4字节)
使用char*进行加加的时候,每次加加的宽度为char(1字节)
使用cshort*进行加加的时候,每次加加的宽度为short(2字节)

当星号大于等于2个的时候(int*),无聊星号有多少个(int*****…),无论是char还是short,加加以后宽度永远是4



指针的加减乘除

error C2296: “*”: 非法,左操作数包含“int *”类型
a += 5; a1 += 5; a2 += 5;
b += 5; b1 += 5; b2 += 5;
c += 5; c1 += 5; c2 += 5;

在这里插入图片描述

结论:
指针无法使用乘除运算
使用int,short,char进行运算的时候,会对a,b,c里面的值0进行加五的操作
使用int*,short*,char进行运算的时候,a1是int,得到的值,实际上是int或者char去掉一个以后的宽度乘以5,45=20,15=5,25=10
使用int**,short**,char**进行运算的时候,无论加多少,都是4*N



指针间的运算

char* a=(char*)200;
char* b = (char*)100;
int x = a - b;
printf("%d", x);//输出100

在这里插入图片描述

结论:
两个类型相同的带类型的变量可以进行减法操作
想减的结果要除以去掉一个
的数据的宽度



指针的比较

在这里插入图片描述
结论:
带*的变量,如果类型相同,可以做大小的比较



&符号的使用

char a = 10;
short b = 20;
int c = 30;

char* pa = (char*)&a;
short* pb = (short*)&b;
int* pc = (int*)&c;
//简写为
char* pa = &a;
short* pb = &b;
int* pc = &c;

当我们使用一个变量的时候,可以使用&符号来取得变量的地址

char a = 10;
char* pa = &a;

printf("%d", *pa);

当我们使用*pa的时候,可以读取某个地址里面的值

char a = 10;
char* pa = &a;
char** ppa = &pa;

printf("%d", *(*ppa));

当ppa里面存了pa的地址,pa里面存了a的地址
使用*ppa取到的是pa的地址,*pa取到a的地址

char a = 10;
char* pa = &a;
char** ppa = &pa;
char*** pppa = &ppa;
char**** ppppa = &pppa;

printf("%d", *(*(*(*ppppa)))); //10

总结:
类型的变量,可以通过在其变量前加来获取其指向内存中存储的值
在带类型的变量前面加,类型是其原来的类型减去一个
*



使用数组操作指针

char arr[9] = {1,2,3,4,5,6,7,8,9};

char* p = &arr[0]; //取数组第一个元素的地址
char* p2 = arr;

printf("arr[0]---%d\n",*(p+0));
printf("arr[1]---%d\n", *(p + 1));
printf("arr[2]---%d\n", *(p + 2));
printf("arr[3]---%d\n", *(p + 3));
printf("arr[4]---%d\n", *(p + 4));
printf("arr[5]---%d\n", *(p + 5));
printf("arr[6]---%d\n", *(p + 6));
printf("arr[7]---%d\n", *(p + 7));
printf("arr[8]---%d\n", *(p + 8));

取得数组里面的第i个,然后读取
在这里插入图片描述

*总结:
&arr[0]代表取数组中第一个元素的地址,可以省略为数组名
(p+i) = p[i]


扩展:

*(p + i) = p[i]
* (*(p + i) + k) = p[i][k]
* (*(*(p + i) + k) + m) = p[i][k][m]
* (*(*(*(*(p + i) + k) + m) + w) + t) = p[i][k][m][w][t]

* () 与[]可以相互转换
int i = 100;

int* p1 = &i;
int** p2 = &p1;
int*** p3 = &p2;
int**** p4 = &p3;
int***** p5 = &p4;
int****** p6 = &p5;
int******* p7 = &p6;

printf("%d\n", *(*(*(*(*(*(*(p7))))))));

printf("%d\n", *(*(*(*(*(*(*(p7 + 0) + 0) + 0) + 0) + 0) + 0) + 0));

printf("%d\n", p7[0][0][0][0][0][0][0]);


函数指针

变量和结构体可以使用指针,函数也可以
在计算机眼里,变量和函数,都是一个变量,有自己的地址

int Add(int x,int y)
{
	return x + y;
}
int(*pAdd)(int, int);

pAdd = Add;
int x = pAdd(1, 2);


扩展:小端存储以及int指针访问char数组

在这里插入图片描述
int*指针访问char数组已经小端存储使用int指针读出来的数据为什么是反过来的?
在这里插入图片描述
代码

#include "stdafx.h"

void fun()
{
	char a[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, };

	int* p = (int*)a;
	printf("%x\n", *p);
	printf("%x\n", p[1]);
	printf("%x\n", p[2]);
	printf("%x\n", p[3]);
}
int _tmain(int argc, _TCHAR* argv[])
{

	fun();
	
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35425243/article/details/82867102
今日推荐