C语言指针讲解(初识)

1.内存和地址操作符&

目录

1.内存和地址操作符&

2.什么是指针?

3.指针变量的初始化和解引用操作符* 

4.指针的大小

5.指针的运算


 在我们的计算机当中,每一个变量都有自己相应的地址,一个字节在自己相应的内存块,所以地址的另一个名字叫“指针”

 

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	printf("a=%p\n", &a);
	printf("b=%p\n", &b);
	printf("c=%p\n", &c);
	return 0;
}

我们可以看到,在32位的环境下,a,b,c的地址都比上一个变量多四个字节

内存编号=地址=指针 

2.什么是指针?

指针顾名思义就是指向某一个地方的东西,在计算机中就是指向某一块内存,我们要有某个内存的地址才能使用到指针,一个简单的例子。*p=&a。就像你送一样东西给别人,你要知道对方的地址才能送达,&a就是对方的地址,*p就是对方的家。

3.指针变量的初始化和解引用操作符* 

int main()
{
	int a = 123;
	int* p = &a;
	printf("*p=%d\n", *p);
	return 0;
}

我们使用一个取地址操作符&将a的地址存储在指针变量p中

int* p中的int是说明指针变量指向的变量是整型,“*”说明p是一个指针变量,p是变量的名称

解引用操作符*

int main()
{
	int a = 123;
	int* p = &a;
	*p = 10;
	printf("a=%d\n", a);
	return 0;
}

我们可以看到第五行代码,我们使用了解引用操作符,将p指向的地址的变量改成了10,因为p指向的是a的地址,将其解引用来修改值。

4.指针的大小
int main()
{
	printf("%zd\n", sizeof(char*));
	printf("%zd\n", sizeof(short*));
	printf("%zd\n", sizeof(int*));
	printf("%zd\n", sizeof(double*));
	return 0;
}

   

我们可以发现指针变量在32位环境下是四个字节,在64位环境下是8个字节,而且不同类型的指针所占用的字节都是相等的。

5.指针的运算

 指针+-整数

int main()
{
	int n = 10;
	char* pc = (char*)&n;
	int* pi = &n;
	printf("%p\n", &n);
	printf("%p\n", pc);
	printf("%p\n", pc + 1);
	printf("%p\n", pi);
	printf("%p\n", pi + 1);
	return 0;
}

我们可以看到pc+1与pc多跳了一个字节,而pi+1与pi多跳了四个字节,所以指针类型决定指针向前走多少个字节。

指针-指针

int test(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	printf("%d\n", tsst("abc123"));
	return 0;
}

指针的关系运算

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	while (p < arr + sz) //指针的⼤⼩⽐较
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

6.野指针 

野指针就是没有明确表明指向某一块地方,内容是无知的,随机的。

造成野指针的原因如下:

指针为初始化

int main()
{
	int* p;//指针未初始化,默认为随机值
	*p = 10;
	return 0;
}

指针访问越界

int main()
{
	int arr[10] = { 0 };
	int* p = &arr[0];
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		//当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;
}

指针指向空间被释放

int* test()
{
 int n = 100;
 return &n;
}
int main()
{
 int*p = test();//n是局部变量,离开test函数时已经空间已被释放了,所以p是野指针
 printf("%d\n", *p);
 return 0;
}

7.传值调用和传址调用

我们来写一个函数来交换它的两个值

void Swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);
	printf("交换前:a=%d b=%d\n", a, b);
	Swap(a, b);
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}

 

为什么我们没有达到交换的效果呢?

原因是在我们的实参传过去的时候,x和y确实有得到我们20和30这两个数,但是x,y和a,b的地址不同,在离开Swap这个函数的时候,x和y的地址就访问不了了,所以我们的a和b就没有改到相应的值,我们该传地址来交换。

void Swap2(int*px, int*py)
{
 int tmp = 0;
 tmp = *px;
 *px = *py;
 *py = tmp;
}
int main()
{
 int a = 0;
 int b = 0;
 scanf("%d %d", &a, &b);
 printf("交换前:a=%d b=%d\n", a, b);
 Swap1(&a, &b);
 printf("交换后:a=%d b=%d\n", a, b);
 return 0;
}


  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值