浅显易懂C语言指针!!!


前言

印度顶尖程序员Harsha Suryanarayana深入浅出讲解C指针
我在b站上,看印度程序员小哥讲c指针的学习笔记。


Introduction to pointers in C 指针的基本介绍

代码如下(示例):
在这里插入图片描述

//Pointers ---- variables that store address of another variable  指针----是一个变量,它存放着另一个变量的地址
//设变量a的address在204  指针变量p的address在64 如上图
int a;
int *p;//定义了一个 指向a地址的 指针变量 
p = &a;//&是取地址符,这个表达式的意思是 把a的address赋给p;
a = 5;
printf p;//得到的是a的地址204
printf ("%d\n",&a);//204  注意输出格式 
printf &p;//输出的是指针变量p的address
printf *p;//5   p->address    *p->valus at address

//图二
*p = 8;//赋值
printf a;//8

下面是图二
tuer

Working with pointers 指针代码示例

 int a;// integer 声明变量时:变量数据类型 变量名
 int *p;// point to integer 声明指针变量:变量数据类型 *变量名
//其他类型也相似
char c;//character
char *p0;//pointer to character
double d;//double 
dpuble *p1;//pointer to double

p = &a;//取地址操作  上面只是定义指针,还没有赋值 

下面是能正常运行的代码:

#include<stdio.h>
int main()
{
	int a;
	int *p;
	a = 10;
	p = &a;//&a = address of a 
	printf("%d\n",p);//在a没有初始化时,p也就是a的地址是随机的 ,每次分配内存不同
 	printf("%d\n",*p);//*p-  p指向地址的值
	printf("%d\n",&a);
}

利用指针修改变量的值

#include<stdio.h>
int main(){
	int a;
	int *p;
	a = 10;
	p = &a;//address of a 
	printf("*p = %d\n",*p);
	printf("a = %d\n",a);
	printf("a 的地址 %d\n",p);
	
	printf("\n");
	printf("\n");
	*p = 15;//利用指针p修改变量a的值
	printf("利用指针p修改变量a的值\n");
	printf("a = %d\n",*p);//15
	printf("a = %d\n",a);

}

int b = 20;
*p = b;//Will the address in p change to point b??

#include<stdio.h>
int main(){
	int a = 10;
	int *p;
	p = &a;
	printf("Address of P is %d\n",p);//p指向的变量地址是
	printf("Value of p is %d\n",*p);//p指向的变量值是


	int b = 20;
	*p = b;//Will the address in p change to point b?? 
	printf("Address of P is  = %d\n",p);//p still point to a;
	printf("Value of p is  = %d\n",a);//但是改变了a的值a=20
}

定义、初始化 - 简写

int a;
a = 10;
//等同于
int a = 10;


//指针同理
int *p;//指针第一种方式较为常用
p = &a;
//等同于
int *p = &a;

Pointer arithmetic//指针算数运算

#include<stdio.h>
int main(){
	int a =10;
	int *p;
	p = &a;
	//Pointer arithmetic
	printf("Address p is = %d\n",p);//p指向的地址是
	printf("value at address p is %d\n",*p);//10
	printf("\n");

	printf("size of integer is %d btyes\n",sizeof(int));//这个打印语句会告诉我们整型的大小
	printf("\n");
	
	printf("Address (p+1) is  = %d\n",p+1);//p+1会得到下一个整型数据的地址,一个整型的大小是4个字节。
	//也就是说,如果p = 2000,那么(p+1) = 2004;
	printf("value at address (p+1) is %d\n",*(p+1));//一个我们所不知道的随机值,也就是垃圾值。因为我们实际上并没有为这个特定的内存地址分配一个整型变量。这是使用指针算数运算的时候一个危险的地方
	printf("value at address p+1 is = %d\n",*p+1);
	printf("\n");
	
	printf("Address p+2 is = %d\n",p+2);
} 

你可以试着改成用char指针、float指针、double指针或者指向其他类型的指针

Pointers types,void pointer ,pointer arithmetic 指针的类型,算数运算,void指针

指针是强类型的,你需要一个特定类型的指针变量来存放特定类型变量的地址( int型变量就要int指针,char变量就要char指针)。

Why strong types?
Why not some generic type?//为什么指针不是通用的类型呢

我们不仅仅使用指针来存储内存地址,同时也用它来解引那些地址的内容。(//*p = &a:)这样我们就可以访问和修改这些地址对应的值了。

在这里插入图片描述

int-4 byte;
char- 1 byte;
float- 4 byte;
//如上图是一个int型的数,假设4个字节从右往左分别是200,201,202,203
并且根据二进制转是十进制,是1025
 int a = 1025;
 int *p;
 p = &a;
 printf p; //此时输出的是地址应该是  200;
    

地址是起始地址!!!如果我们想知道那个地址的值(内容),就用*p去解引用这个地址。
如果p是一个字符类型的指针,那么在解引用的时候机器只会看1个字节。

让我们写一些程序看会发生什么。

#include<stdio.h>
int main(){
	int a =1025;
	int *p;
	p = &a;
	printf("size of integer is %d bytes\n",sizeof(int));
	printf("Address of p = %d,Value of p = %d\n",p,*p);
	char *p0;
	p0 = (char*)p;//typecasting 强制类型转换
	printf("size of char is %d bytes\n",sizeof(char));
	printf("Address  of p0 = %d,Value of p0 = %d\n",p0,*p0);

	//1025 = 00000000 00000000 00000100 00000001 
	//当我们强制转换为char时,最右边的这个字节的地址会被存入'p0',
	//(这里要注意大小端……我还不知道大小端是什么……可能就是从左往右的顺序。)
	//当机器解引p0时,会认为它是一个指向字符型的指针,字符型只有1个字节所以机器只看一个字节,即00000001 = 1

	//我们再来看看p+1 和p0+1
	printf("Address of p+1 = %d,Value of p+1 = %d\n",(p+1),*(p+1));//按理说因为没有指定p+1的值
	//所以*(p+1)会出现一个随机值(垃圾值),但是我不知道为什么我的跑出来是p指向的地址,每次运行都是
	printf("Address of p0+1 = %d,Value of p+1 = %d\n",(p0+1),*(p0+1));
	//00000000 00000000 00000100 00000001 ,p0+1会向左移动,即00000100 = 4;
	}

在这里插入图片描述
以上我们讲解的时 解引用一个指针变量的时候内存中将会发生什么,以及对指针进行特定类型的算数操作(事实上,唯一的指针运算就是以整数值大小增加减少 来改变指针值)会发生什么。

void 类型指针//通用类型指针

不针对某个特定的数据类型

#include<stdio.h>
int main(){
	int a = 1025;
	int *p;
	p = &a;
	printf("size of integer is %d bytes\n",sizeof(int));
	printf("Address of p = %d,Value of p = %d\n",p,*p);
	//Void pointer - Genric pointer
	void *p0;
	p0 = p;//这是合法的,不会有任何编译错误。
	printf("Address of p0 is %d\n",p0);//但是不能 value = %d,*p0;我们会得到一个编译错误(我也不知道为什么这里不是随机值)
	//printf("Address of (p+1) is %d\n",(p0+1));
	//这个也会出现编译错误。因为void没有规定的字节数,所以不知道加多少
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值