变量:是一个标识符(identifier),用来指代一块内存区域,使用变量使我们操作内存以区域(area),以块(block)为单位,提高了方便性。变量是内存区域的别名,机器代码中,是不会出现变量名的;变量名是给我们程序员操作内存来使用的,机器码中将变量名替换成了相应的内存地址。
当我们定义int a时,编译器负责为程序预留4字节空间,并把我们的变量名“a”保存进符号表,并用这个符号表的索引对应实际的空间。如果下面出现b = a;那么它就会根据符号表找到变量的真正的物理位置,取得它的值,赋给b。变量名虽然不直接表示地址,但可用取地址符号&来获得它所代表的变量的存放地址。因为在定义变量的同时会分配给它相应的空间。 使用变量来对数据的访问是直接访问。
a为数组名,表示数组的首地址,在计算数组中元素的值就是通过这个首地址+数据类型*偏移值而得到的。a=&a[0],因此,a是常量,不能进行a++。
PRintf("%d/t",*(array+1)); int *parray=(int *)(&array+1); printf("%d/n",*(parray-1));在array+1过程中,偏移后的地址为array+sizeof(array)*1;而parray=(int )(&array+1),偏移后的地址为array+sizeof(*&array)*1。 array与&array的值是一样的,都是该数组的首地址,但他们的含义是不一。 array表示该数组的首地址,及首元素的地址;而&array指向整个数组的内存块,每次+1时,array偏移一个类型大小,而&array偏移整个数组的内存块大小,。
指针变量存储的是变量的地址,通过指针变量是对数据的间接访问。
main.c extern char str[]; int main(void) { printf("%s/n",str); return 0; }test.c int *str="guidao/n";extern char str[]欺骗了编译器,将指针类型的str当成了数组类型来进行解析,输出的是一个错误的字符串,那这个错误的字符串是怎么得到的。由于欺骗了编译器,将str当成了数组,但是str是一个指针,保存了”guidao/n”这个字符串在常量区的首地址,假如地址为0x01880000,使用printf(“%s/n”,str)时,由于编译器将str当成了数组,直接将地址0x01880000解析输出出来,因此我们看到了错误的值,如果想正确输出,则可以强制转化,改为:
printf("%s/n",(char *)(*(unsigned int *)str));数组是直接访问,而指针是间接访问。
int array[5] = {1,2,3,4,5};array[3]读取数值时,通过array + 3*sizeof(*array)来得到地址,从而得到值,而使用:int *parray = array +3;可以直接得到偏移量,使用指针速度会更快。
int array[5] = {1,2,3,4,5};int *parray = array +3;array[3]=10;*paray = 10;汇编代码
array[3] = 10;00DB1411 mov eax,4 00DB1416 imul ecx,eax,3 00DB1419 mov dWord ptr array[ecx],0Ah *parray = 10;00DB1421 mov eax,dword ptr [parray] 00DB1424 mov dword ptr [eax],0Ah使用指针汇编代码更优化。
char str1[5]={'a','b','c','d','f'};char *str2="guidao/n";str1可读不可写,*str1可读可写,相当于char *const str1; str2可读可写,*str2可读不可写,相当于const char *str2
新闻热点
疑难解答