指针
如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统会根据程序中定义的变量类型,分配一定的内存空间。例如,Visual C++为整型变量分配4个字节,对单精度浮点型变量分配4个字节,对字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。
由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。比如一个房间的门口挂了一个房间号2008,这个2008就是房间的地址,或者说,2008“指向”该房间。因此,将地址形象化地称为“指针”。意思是通过它能找到以它为地址的内存单元。
务必注意存储单元的地址和存储单元的内容这两个概念的区别,假设程序已经定义了3个整型变量i,j,k,在程序编译时,系统可能分配地址为2000 ~ 2003的4个字节给变量 i,2004 ~ 2007的4个字节给 j, 2008 ~ 2011的4个字节给 k。如图所示。
在程序中一般是通过变量名来引用变量的值,例如:
printf("%d\n, i");
实际上是通过变量名i找到存储单元的地址,从而对存储单元进行存取操作的。程序经过编译以后已经将变量名转换为变量的地址,对变量值的存取都是通过地址进行的。
例如有输入语句scanf("%d", &i);
在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中。如果有语句k=i+j;
则从2000 ~2003字节取出i的值(3),再从2004 ~2007字节取出j的值(6),将它们相加后再将其和(9)送到k所占的2008 ~ 2011字节单元中。这种直接按变量名进行的访问,称为“直接访问”方式。
还可以采用另一种称之为“间接访问”的方式,即将变量i 的地址存放在另一变量中,然后通过该变量来找到变量i 的地址,从而访问i 变量。
在C语言程序中,可以定义整型变量、浮点型变量、字符变量等,也可以定义一种特殊的变量,用它存放地址。假设定义了一个变量i_pointer,用来存放整型变量的地址。可以通过下面语句将i的地址存放到i_pointer中。
i_pointer = &i; //将i的地址存放到i_pointer中
这时,i_pointer的值就是2000。
一个变量的地址称为该变量的“指针”。例如,地址2000是变量i 的指针。如果有一个变量用来存储另一个变量的地址,则它称为指针变量。上述的i_pointer就是一个指针变量。指针变量就是地址变量,用来存放地址,指针变量的值是地址。
指针变量的定义、使用及大小
指针变量的定义与使用
#include<stdio.h>
int main()
{
int num = 10;
int *p = #
*p = 20;
printf("%d/n",num);
return 0;
}
指针变量的大小
#include<stdio.h>
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d/n",sizeof(char*));
printf("%d/n",sizeof(short*));
printf("%d/n",sizeof(int*));
printf("%d/n",sizeof(double*));
return 0;
}
结构体
结构体使得C语言有能力描述复杂类型。比如描述学生,学生包含:名字+年龄+性别+学号 这几项信息。这里只能用结构体来描述了。
例如:
struct Stu
{
char name[20]; //名字
int age; //年龄
char sex[5]; //性别
char id[15]; //学号
}; //;用来结束结构体的定义
结构体的初始化:
// 打印结构体的信息
struct Stu s = {"蓝天", 20, "男", "20180101"};
// .为结构体成员访问操作符
printf("name = %s age = %d sex = %s id = %s\n",s.name,s.age,s.sex,s.id);
// ->操作符
struct Stu *ps = &s;
printf("name = %s age = %d sex = %s id = %s\n",ps->name,ps->age,ps->sex,ps->id);