c语言指针

。mage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTc0NDk4Ng==,size_16,color_FFFFFF,t_70)
二,指针变量
在这里插入图片描述

在这里插入图片描述

怎样引用指针变量
在引用指针变量的时候有三种情况:
1:给指针变量赋值 如:p=&a; //把a的地址赋给指针变量p ,指针变量p的值是a的地址,p指向a。
2:引用指针变量指向的变量。
如果已执行“p=&a;”,即指针变脸p指向了整型变量a,则printf("%d",*p);
其作用是以整型形式输出指针变量p所指向的变量的值,即变量a的值。
如果有以下赋值语句:
*p=1;
表示将整数1赋值给p当前所指向的变量,如果p指向a,则相当于把1赋值给a,即“a=1”
引用指针变量的值。如:
printf(“%o”,p);
作用是以八进制数形式输出指针变量p的值,如果p指向了a,就是输出了a的地址,即&a。
*指针运算符(或称“间接访问”运算符),*p代表指针变量p所指的对象

#include <stdio.h>
int main()
{
 int *p1, *p2, *p, a, b;	//p1,p2的类型是int *类型
 printf("please enter two integer numbers:");
 scanf_s("%d%d", &a,&b);	//输入两个整数
 p1 = &a;					//使p1指向a
 p2 = &b;					//使p2指向b
 if (a < b)					//如果a<b
  {						//p1与p2互换
  p = p1;
  p1 = p2;
  p2 = p;
  }
 printf("a=%d,b=%d\n", a, b);	//输出a,b
 printf("max=%d,min=%d\n", *p1, *p2);//输出p1,p2所指变量
 return 0;
}
运行结果:
please enter two integer numbers:5,9
a=5,b=9;
max=9,min=5

sizeof:计算数据空间的字节数
1,与strlen()比较
stren()计算字符数组的字符数,以“\0“为结束判断,不计算‘、0’的数组元素。
而sizeof计算数据(包括数组,变量,类型,结构体等)所占空间,用字节数表示。
2,指针与静态数组的sizeof的操作
指针均可以看作变量类型的一种。所有指针变量的sizeof操作均为4。
注意:int p;sizeof§=4;
但sizeof相当于sizeof(int);
对于静态数组,sizeof可直接计算数组大小;
例: inta[10];charb[]=“hello”;
sizeof(a)等于4
10=40;
sizeof(b)等于6;
注意:数组做型参时,数组名称当做指针使用!
void fun(charp[])
{sizeof§=4}
深度思考
double *(*a)[3][6];
count<<sizeof(a)<<endl;// 4 a为指针
count<<sizeof(*a)<<endl;//72 a为一个有36个指针元素的数组
count<<sizeof(**a)<<endl;//24 **a为数组一维的6个指针
count <<sizeof(***a)<<endl;//4 ***a
为一维的第一个指针
count<<sizeof(****a)<<endl;//8 a为一个double变量
问题解析:
a是一个很奇怪的定义,它表示一个指向double
[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。
既然a执行double
[3][6]类型的指针,a就表示一个double[3][6]的多维数组类型,因此sizeof(a)=36
sizeof(double
)=72
同样的,*a表示一个double [6]类型的数组,所以sizeof(**a)=6sizeof(double)24。
*a表示其中一个元素,也就是double了,所以sizeof(a)=4。
至于
a,就是一个double了,所以sizeof(****a)=sizeof(double)=8。
3.格式的写法
sizeof操作符,对变量或者对象可以不加括号,但若是类型,需加括号。

数组变量本身表达地址,所以
int a[10];int *p=a//无需用&取地址
但是数组单元表达的是变量,需要用&取地址
a==&a[0]
[]运算符可以对数组做,亦可以对指针做
数组变量是const指针,因此两个数组之间不能直接赋值
三,指针与const
指针本身可以是const,它指向的变量,也可以是const
1:指针是const:
表示一旦得到了某个变量的地址,不能再指向其它变量
int *const q=&i;//q是const
*q=26;//OK
q++; //ERROR
2:所指是const
表示不能通过这个指针去修改那个变量(并不能使得那个变量成为cost)
const int *p=&i;
*p=26;ERROR!(*p)是const
i=26;//OK
p=&j;//OK
转换
总是可以把一个非const的值转换成const的
void f(const int *x);
int a=15;
f(&a);//ok
const int b=a;
f(&b); //OK
b=a+1; //ERROR
当要传递的参数的类型比地址大的时候,这是常用的手段:既能用比较少的字节数传递值给参数,又能避免函数对外面的变量的修改
const数组
const int a[]={1,2,3,4,5,6,};
数组变量已经是const指针了,这里的const表示数组的每一个单元都是cnst int 所以必须通过初始化赋值

四,指针运算
例:int *p=&i;// 假设i地址为0xbffbad50
则p+1运算结果为i的地址家sizeof(int);
俩指针相减,其结果为地址相减除以一个“sizeof”
(相当于两指针单元的单元差)
0地址:
当然你的地址中有零地址,但是零地址通常是一个不能随便碰的地址。
所以你的指针不应该具有0值
因此可以用0地址来表示特殊的事情:
返回的指针是无效的
指针没有被真正初始化(先初始化为0)
NULL是一个预定定义的符号,表示0地址
有的编译器不愿意让你用0来表示0地址
指针的类型
无论指向什么类型,所有指针的大小都是一样的,因为都是地址
但是指向不同类型的指针是不能直接相互赋值的
这是为了避免用错指针

五,指针与数组
c语言调用函数时虚实结合的方法都是采用“值传递”的方式,当用变量名作为函数参数时传递的是变量的值,当数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的是值是地址,所以要求形参为指针变量。
在用数组名作为函数实参时,既然实际上相应的形参是指针变量,为什么还允许使用形参数组的形式呢?这是因为在c语言中下标法和指针法都可以访问一个数组(如果有一个数组a,则a[i]和*(a+i)无条件等价),用下标法表示直观,便于理解。因此许多人愿意用数组名作形参,以便与实参数组相对应。从应用的角度看,用户可以认为有一个形参数组,它从实参数组那里得到起始地址,因此形参数组与实参数组共用一个数组单元,在调用函数期间,如果改变了形参数组的值,也就是改变了实参数组的值。在主调函数中就可以利用这些已改变的值。对c语言比较熟悉的专业人员往往喜欢用指针变量作形参。
注意:实参数组名代表一个固定得地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量处理。
补充(实参和形参)
1:形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后不能再使用该形参变量。
2:实参可以是常量,变量,表达式,函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有具体的值,以便把这些值传递给形参。因此应预先用赋值,输入等办法使形参获得确定的值。
3:实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配的错误。
4:函数调用中发生的数据传递是单向的。即只能把实参的值传给形参,而不能把形参的值反向传递给形参。因此在函数调用过程中,形参的值发生变化,而实参中的值不会变化。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值