2021-7-25

定义的是指针变量,存放的是地址这个值

int* fun()
{
	int ar[10] = { 12,23,34,45,56,67,78,89,90,100 };
    //如果数组开辟空间很大,可正常打印
    //没有对原来的数据进行覆盖
	int* p = ar;
	return p;
}
int main()
{
	int* p = fun();
    //调用完之后,将空间还给栈,此时指针已失效,没有所指的空间
		for (int i = 0; i < 10; ++i)
		{
			printf("%d\n", p[i]);
		}
	printf("\n");
}
int main()
{
	int a = 0x12345678;
	int* ip = &a;
	char* cp = (char*)&a;
	char* p = (char*)&a;
	*p = 'a';
	p = p + 1;
	*p = 'b';
	p = p + 1;
	*p = 'c';
	p = p + 1;
	*p == 'd';
	return 0;
}

X86—小端存放

指针+1和自身类型有关,与所指之物无关

首地址从低地址开始

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6WwWiXiF-1627967914588)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210802180007082.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZP1Sy8U9-1627967914591)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210802180717411.png)]

int main()
{
	sizeof(ar);//elem num,elem type
	//其他情况下均为数组首元素的地址
	int* ip = ar;//&ar[0]
	&ar;//数组的地址
	int(*s)[5] = &ar;
	//s开辟出4个字节,s:一个指针空间
	int* pa[5];
	return 0;
}
s=&ar;//数组的地址
ip=ar;//数组首元素的地址

大小相同,类型不同(指针+1的能力不同)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uojzoqoy-1627967914594)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210802181737931.png)]

同类型指针相减,减后的结果是此类型的元素个数,不是字节个数

void
    函数不需要返回值时,void fun(a)
    函数不允许接受参数时,int fun(void)
    限定运算操作,不允许参与运行
    断言不参与任何运算,把值强转为无类型
    assert(dest != nullptr && src != nullptr);//right
	assert(dest != nullptr) && (src != nullptr);//error

void

不可以定义变量,但可以定义指针变量

void指针可以指向任意类型变量的地址

    char ch = 'a';
	int x = 10;
	double dx = 12.23;
	void* vp = &ch;
	vp = &x;
	vp = &dx;
int main()
{
	const int n = 5;
	int ar[n] = { 12,23,34,45,56 };
	void* vp = ar;
	vp = &ar;
	int a = 10;
	int* ip = &a;
	vp = &ip;
	vp = &vp;
	sizeof(vp);//可以确定指针的大小,不能确定所指之物的大小
	sizeof(*vp);//error,不知道它是什么类型
}

GUN中允许,void* 和 char* 等价

不同的标准,无类型有不同的规范

函数的形参为 void* 指针变量时,函数就可以接受任意类型变量的地址
void my_memset(void* src, unsigned char val, size_t count)
{
	assert(src != nullptr);
	char* cp = (char*)src;
	for (int i = 0; i < count; ++i)
	{
		*cp = val;
		cp = cp + 1;
	}
}
int main()
{
	const int n = 5;
	int ar[n];
	char cr[n];
	double dr[n];
	my_memset(ar, 0, sizeof(int) * n);//字节个数
	my_memset(cr, 0, sizeof(char) * n);
	my_memset(dr, 0, sizeof(double) * n);
}
//my_memset  内存拷贝
//count字节个数
void my_memcpy(void* dest, const void* src, size_t count)
    //使用 void* 类型,提高其通用性
{
	assert(dest != nullptr && src != nullptr);
	char* darg = (char*)dest;
	const char* sarg = (const char*)src;
    //忽略类型,全部以字节形式表示
	for (int i = 0; i < count; ++i)
	{
		*darg++ = *sarg++;
	}
}
int main()
{
	const int n = 5;
	int ar1[n] = { 12,23,34,45,56 };
	int ar2[n];
	double dr1[n] = { 1.2,2.3,3.4,4.5,5.6 };
	double dr2[n];
	my_memcpy(ar2, ar1, sizeof(int) * n);
	my_memcpy(dr2, dr1, sizeof(double) * n);
	return 0;
}

将字符串库里面的函数编译运行出来,调用是基础操作,必须得知道库函数是如何实现的

小厂:strlen strcmp strcat strcpy

大厂:memmove(为什么把形参设计成无类型指针,其好处是什么?)

​ 函数内部,无类型指针无法对内存进行解析,所以要对它进行强转

​ atoi—很重要

int my_strcmp(const char* ap, const char* bp)
{
	assert(ap != nullptr && bp != nullptr);
	while (*ap != '\0' && *bp != '\0' && *ap == *bp)
	{
		ap++;
		bp++;
	}
	return (*ap - *bp);
}
int my_strcmp(const char* ap, const char* bp)
{
	assert(ap != nullptr && bp != nullptr);
	int k = 0;
	while ((k = *ap - *bp) == 0 && *ap++ &&* bp++);
	return k;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值