梗概
一、指针变量
在了解指针之前先要弄清楚地址的概念。
如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统 根据城西中定义的变量类型,分配一定长度的空间。
例如:整型变量分配4个字节,字符型分配1个字节,单精度分配4个字节等。
内存区的每一个字节有一个编号,这就是“地址编号”,它就相当于旅馆中的 房间号,每一个房间都可以看作一块内存区域,都可以用来存放东西,我们给每个房间都编一个房间门 牌号,用于更好的区分每一个房间,内存中也是一样的,整个内存由很多个字节组成,每个字节都有其 对应的“房间号”,这就是“地址”了。
通过这个“房间号”就可以找到其对应的“房间”,然后就可以从房间里 取东西,或者把东西放进房间里了。
理解了地址的概念之后,那所谓的指针,就是内存地址,也就是地址的编号,可以把“指针指向地址” 理解成“用小本本把房间号记下来”,那这个小本本就相当于一个用于记房间号的指针了,一个变量的地址称为此变量的“指针”。
指针有指针常量与指针变量之分,For example:&a是指针常量,用基类型与解引用符定义的p是指针变量。
因此要区分好相关运算符:
二、指针与函数
两种应用:1、函数参数为指针类型的函数
函数的参数不仅可以是整型、浮点型、字符型的数据,还可以是指针类型。它的作用是将一个变量的地 址传递到另一个函数,如:
void fun1(int x,int y)
{//这里定义了一个普通函数fun1
printf(“x=%d\ty=%d\n”,x++,y++);
}
void fun2(int *x,int *y)
{//这里定义了一个形参为整型指针类型函数fun2,其形参为指针类型的变量
printf(“x=%d\ty=%d\n”,(*x)++,(*y)++);
//注意:和printf(“x=%d\ty=%d\n”,*x++,*y++);的区别,也就是有括号和没有括号的区别
}
int main()
{
int a=10,b=20,*p,*q;
fun2(&a,&b); //这里调用函数fun时,所传递的实参必须是地址
p=&a; //使用整型指针变量p指向整型变量a的地址
q=&b; //使用整型指针变量q指向整型变量b的地址
printf(“a=%d\tb=%d\n”,*p,*q);
fun2(p,q); //这里使用指针变量p和q作为实参传递
printf(“p=%d\tq=%d\n”,*p,*q);
return 0;
}
调用函数,传地址:
在函数的形参列表中定义指针变量
一个小插曲~🦉
w(゚Д゚)w 这是 c语言语法基础
名称 | 值 | 类型 | |
---|---|---|---|
▶ | &name | 0x00000064171ef8a4 <字符串中的字符无效。> | char * |
小插曲先到此结束吧(如果有大佬指点迷津那就再好不过了)
2、指针函数
返回值为指针类型的函数称为“指针函数”。
注意:不要反馈出一个局部变量的地址——
#include<stdio.h>
//反馈出一个整型变量的地址 ——是什么类型吗?int*
int* fun()
{
int a = 10;//是一个局部变量,作用范围:函数体
int*p = &a;
return p;
}//不要反馈出局部变量的地址
int main()
{
int*p1 = fun();
printf("%d\n", *p1);//这样做有问题
printf("%d\n", *p1);
return 0;
}
正确示范:
int* fun3(int *x,int y)//这是一个指针函数,返回值类型为整型int指针类型
{
*x+=y;
printf(“%d”,++*x);
return x; //返回指针变量x所指向的内存地址
}
指针函数使用场景:(在学习c++开辟动态内存时会用到)
需要去占用一块连续的存储空间,该函数反馈出这个空间首地址,方便我们管理该空间。
三、指针与数组
1、指针指向数组元素、指针指向的移动
整型的数组会发现它们的地址不是连续的,而是相差4;因此,假使 定义一个数组指针
int *p=arr;//就是定义在数组的首地址,相当于 int *p=&arr[0];
那么p+1式子的结果是p下一个元素的地址
p+1 表达式的结果,加的是一个基类型(如果是地址值加1,就没有意义了)
因此指针偏移的含义为:指针每次会以其基类型所占字节数为单位进行偏移
注意:自增自减运算、赋值运算符才能改变变量自身的值——
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++) {
printf("arr[%d]的地址是%#p\n", i, &arr[i]);
//%#p 显示十六进制的前缀0x
}
int* p = arr;
p + 4;
printf("直接把p+4这个表达式放在运行代码里,p的地址是%#p,对照前面看没变\n", p);
printf("正确使用表达式,首位数组元素往后三位的元素是%d,它的地址是%#p\n", *(p + 3),(p+3));
printf("正确使用表达式,首位数组元素往后三位的元素是%d,它的地址是%#p,这里用的是方括号,它们的作用是等价的",arr[3],&arr[3]);
}
[ ]也有解引用的 作用
在上述代码中,
arr[3] 等价 *(arr+3)另外,p[3]也就是arr[3]的地址,即&arr[3]。
2、指针指向字符串
有意思——除了通过数组输出字符串,还可以用指针变量表示它:
char *p = “abcdefg”;
puts(p);
while (*p)
{
printf("%c\t", *(p++));
}
由于C语言中没有真正的字符串类型,可以通过字符数组表示字符串,因为它的元素地址是连续的,这就足够了。
C语言中规定数组代表数组所在内存位置的首地址,也是 str[0]的地址,即str = &str[0];
而printf(“%s”,str); 为什么用首地址就可以输出字符串?
举例:
char *s ;
s = “China”;
为什么可以把一个字符串赋给一个指针变量?C语言中编译器会给字符串常量分配地址,如果 “China”, 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 .
s = “China” ,其实真正的意义是 s =”China” = 0x3000;
————————————————
版权声明:本文为CSDN博主「xumengfan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xumengfan/article/details/78148317
当用sizeof 测字节大小是,指针变量都是4字节,32位。