第一阶段 C语言基础与入门9

1.数组

p162

2.找出矩阵中的最大值(二维数组的应用)

3.指针和地址

1. 地址

地址和指针是两个重要的概念,在程序运行中,变量或者程序代码会被存储在以字节为单位组织的存储器中。在C语言中,如果定义了一个变量,在编译时就会根据该变量的类型给它分配相应大小的内存单元。

例如int类型占2个字节,需要分配2个字节的内存单元,char型变量需要分配1个字节的内存单元,float型变量和double型变量则需要分配4个字节和8个字节的内存单元。

计算机对内存单元的数据操作一般是按“地址”存取的,也就是对内存单元进行编号。

因为int型变量的存储长度为2个字节,所以C语言编译器将它们分配到的地址为1000~1001、1002~1003和1004~1005的内存单元中,而程序执行时是将变量翻译为它所在的内存地址进行操作的。

int x=20,y=1,z=155;

如调用函数printf("%d",x):将x所在的内存地址1000~1001单元的内容按照整数格式输出。这种使用变量的方法叫做“直接访问”。一般以变量所在的内存单元的第1个字节地址作为它的地址,如上述代码中变量x的内存地址为1000,y的内存地址为1002,z的内存地址为1004。而它们的内容分别为20,1,155。

2.指针

       在C语言中还有一种使用变量的方法,即通过变量的地址进行操作:用指针访问内存和操纵地址。假设再定义一个变量p,它位于2000单元,该单元中存放了变量x的地址1000。此时,取出变量p的值1000,就可以访问访问内存为1000的单元,实现对变量x的操作,也就是说通过变量p,就可以间接访问变量x。
      在C语言中把这种专门用来存放变量地址的变量称为“指针变量”,简称为指针。

       C语言使用指针对变量的地址进行操作。指针是用来存放内存地址的变量,如果一个指针变量的值是另外一个变量的地址,那么就称指针变量指向那个变量。前面提及的p就是指针变量,它存放了变量x的指针地址,即指针变量p指向变量x。

4.指针变量的定义

  如果在程序中声明一个变量并使用地址作为该变量的值,那么这个变量就是指针变量,一般形式为:

   类型名  *指针变量名

   这里变量 p是指向int型变量的指针。指针值可以是特殊的地址0,也可以是一个代表机器地址的正整数。

注:指针声明符 * 在定义指针变量时被使用,说明被定义的那个变量为指针

注:指针变量的类型并不是指针变量本身的类型,而是指它所指向的变量的数据类型。无论何种类型的指针变量,它们都是用来存放地址的,因此指针变量自身所占的内存大小和它所指向的变量数据类型无关,尽管不同类型的变量所占的内存空间不同,但不同类型指针变量所占内存空间大小都是相同的。

int i, *p;   //定义指针变量p
p=&i;    //指针p是存放变量i的地址
p=0; //空指针
p=NULL; //空指针
p=(int*)1732; //使用强制类型转换(int*)来避免编译错误,表示p指向地址为1732的int型变量

在定义指针变量时,要注意:

1.指针变量名是一个标识符,要按照C标识符的命名规则对指针变量进行命名。

2.指针变量的数据类型是它所指向的变量的类型,一般情况下一旦指针变量的类型被确定后,它只能指向同种类型的变量

3.在定义指针变量时需要使用指针声明符*,但指针声明符并不是指针的组成部分。例如定义int *p;时,说明p是指针变量,而不是*p。

5.指针的基本运算

      如果指针的值是某个变量的地址,通过指针就能间接访问那个变量,这些操作由取地址运算符&和间接访问运算符 * 完成。此外,相同类型的指针还能进项赋值、比较和算术运算。

     1. 取地址运算和间接访问运算

单目运算符 & 用于给出变量的地址。例如:

int *p,a=3; //p指针用来存放a的地址
p=&a;  //用运算符&来读取a的地址,并将这个地址值作为指针p的值,使指针p指向变量a。

  注:指针的类型和它所指的变量的类型必须相同。

在程序中,* 除了用于定义指针变量外,还被用于访问指针所指向的变量,它也称为间接访问运算符。例如,当p指向a时,* pa访问同一个存储单元,* p的值就是a的值。* p就相当于a

下面通过实践,对这些概念进行更深入的了解:

/*取地址运算和使用指针访问变量*/
#include<stdio.h>
int main()
{
	int a=3,*p;   //定义整型变量a和整型指针p
	p=&a;   //把变量a的地址赋值给指针p,即p指向a
	printf("a=%d,*p=%d\n",a,*p);  //输出变量a的值和指针p所指向的值
	*p=10;    //对指针p所指向的变量赋值,即对变量a赋值 
	printf("a=%d,*p=%d\n",a,*p);   输出改变后变量a的值和指针p所指向的值
	printf("Enter a:");
	scanf("%d",&a);      //输入a 
	printf("a=%d,*p=%d\n",a,*p);   
	(*p)++;   //将指针所指向的变量加1
	printf("a=%d,*p=%d\n",a,*p);
	
	return 0; 
} 

 第一次出现的*p和后出现的*怕,尽管形式是相同的,但含义不相同。第一次的定义了指针变量,p是变量名,*表示的是其后变量为指针。第二次出现的*p代表p所指向的变量。

注:*p=*p+1、++*p和(*p)++,都是将指针p所指向的变量的值加1。而*p++等价于*(p++),先取*p的值作为表达式的值,再将指针p的值加1,运算后,p不再指向变量a。

#include<stdio.h> 
int main()
{
	int a=1,*p;
	p=&a;
	printf("a=%d,*p=%d\n",a,*p);
	*p++;
	printf("a=%d,*p=%d\n",a,*p);
	return 0;
}

#include<stdio.h> 
int main()
{
	int a=1,*p;
	p=&a;
	printf("a=%d,*p=%d\n",a,*p);
	(*p)++;
	printf("a=%d,*p=%d\n",a,*p);
	return 0;
}

 观察两者,不难发现区别。

再进行深入了解:

#include<stdio.h> 
int main()
{
	int a=1,*p;
	p=&a;  //将a的地址赋值给变量p 
	printf("a=%d,*p=%d\n",&a,p);
	*p++;
	printf("a=%d,*p=%d\n",&a,p);
	printf("a=%d,*p=%d\n",a,*p);
	return 0;
}

 

 由此可见,p与a的地址在*p++后已不相同,因此p不再指向变量a。

2. 赋值运算
一旦指针被定义并赋值后,就可以如同其他类型变量一样进行赋值运算,例如:

int a=3,*p1,*p2; //定义整型变量指针p1和p2
p1=&a;        //使指针p1指向整型变量a
p2=p1;
printf("*p1=%d,*p2=%d",*p1,*p2);
return 0; 


将变量a的地址赋给指针p1,再将p1的值赋给p2,因此指针p1和指针p2都指向变量a。此时,*p1,*p2和a访问同一个储存单元,它们的值都一样。

给指针赋值是使指针和所指向变量之间建立关联的必要过程。指针之间的相互赋值只能在相同类型的指针之间进行,可以在定义时对指针进行赋值,也可以再程序运行过程中根据需要对指针重新赋值,但要特别注意:指针只有在被赋值以后才能被正确使用。

注:只能将一个指针的值赋给另一个相同类型的指针。

                                                                                     好久没打卡C了,重新开始C的自学旅程!

如有错误,欢迎指出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值