C语言呢是大一时候学的,现在回想起来课程大体的内容是对编程能力的培养,学校有OnlineJudge平台,用于平常的做题以及考试,这些题看起来更像是考察逻辑思维能力,我在这一方面的表现平平。整个学期下来,基本语法虽说学到了指针,但是对指针的讲解还是不够多,对指针有种朦朦胧胧的感觉。
指针
取地址
每一个变量都在内存中有个位置,这个位置称为地址,当我们需要知道这个变量的地址时使用"&"可以取到,该变量的地址。示例1:
#include <stdio.h>
int main ()
{
int var1;
char var2[10];
printf("var1 变量的地址: %x\n", &var1 );
printf("var2 变量的地址: %x\n", &var2 );
return 0;
}
结果:
var1 变量的地址: bff5a400
var2 变量的地址: bff5a3f6
什么是指针?
指针是一个变量,存放的是另一个变量的内存地址,星号*用来声明该变量是个指针。示例2:
int *ip; /* 一个整型的指针 */
double *dp; /* 一个 double 型的指针 */
float *fp; /* 一个浮点型的指针 */
char *ch; /* 一个字符型的指针 */
在这个示例中,ip,dp,fp,ch都是指针,它们的数据类型都是代表内存的长的十六进制数,但是指向的变量的数据类型不同,也就是*ip和*dp数据类型不同,一个是int,一个是double。
绕个弯弯
前面示例1中,打印数组的地址,采用了"&var2"的方式:
printf("var2 变量的地址: %x\n", &var2 );
实际上,很久没接触会觉得这不是取地址的地址也就是指向存放var2这个指针的指针,打印数组的地址,这样不就行了:
printf("var2 变量的地址: %x\n", var2 );
结果是一样的:
var2 变量的地址: bff5a3f6
结果是一样,但仔细一想,如果一样何必加个"&"。实际上两者类型不一样,var2指向的是var2[0]的地址,也就是&var2[0],&var2则是代表整个数组的地址,通过对数组名加减操作能看出两者区别:
int arr[5] = { 1, 2, 3, 4, 5 };
printf("%d\n", *arr);//得到数组第一个元素arr[0]
printf("%d\n", *(arr + 1));//得到数组第二个元素arr[1],地址加sizeof(int),如64位下为4
printf("%d\n", *((int*)(&arr + 1)));//加1相当于&arr[5]+1,也相当于地址加了20(4*5),也就是arr[5]所在地址的后面一个地址,得到未定义的值
printf("%d\n", *((int*)(&arr + 1) - 1));//转换成int *类型(或其它类型T),减一操作将会以sizeof(int*)(或sizeof(T))为移动单位,指向5
结果:
1
2
-858993460
5
网友评论