指针进阶(二)

(1)指针就是地址,也就是说在某一位数确定的操作系统中,他的范围是可以确定的,就是说指针变量的sizeof值是相等的。
比如32位系统下,不管是指向char、int、还是long型变量的指针,他的大小都是4字节
(2)sizeof是关键字,求值是发生在编译的时候,他不同于函数,因为函数的求值是发生在运行的时候。且看:
int ch[6];
sizeof(ch[6]);//是存在的,值为4,编译是不会报错的
(3)数组int a[5];的&a和a代表的含义
&a:是数组a的起始地址,那么&a+1是指向下一个数组即指向了元素a[5],不是下一个元素a[1]哦
a:是数组第一个元素a[0]的地址,它相当于&a[0]
#include <stdio.h>
#include <string.h>
int main()
{
	int a[5]={1,2,3,4,5};
	int *ptr=(int *)(&a+1);//相当于ptr=a+sizeof(int)*5
	printf("\n*(a+1)=%d   *(&a[0]+1)=%d    *(ptr-1)=%d\n\n",*(a+1),*(&a[0]+1),*(ptr-1));
}
运行结果:
*(a+1)=2   *(&a[0]+1)=2    *(ptr-1)=5

(4)定义为数组声明为指针
先看个例子:
file1.c

#include <stdio.h>
char table[20]="ABCDEF";
void Display_TabAddr(void)
{
	printf("file1:table_addr = 0x%x\n",table);
}
file2.c
#include <stdio.h>
extern char *table;
extern void Display_TabAddr(void);

int main()
{
	Display_TabAddr();	
	printf("file2:table_addr = 0x%x\n",table); 
	return 0;
}
运行结果: 
file1:table = 0x424a30     -->  这才是table数组的真实地址
file2:table = 0x44434241   -->  0x44 0x43 0x42 0x41的意思难道和table[]里边的"D","C","B","A"有关系???
Press any key to continue
结果分析:
①在file2.c中的table是一个指向char型的指针变量,他占有4字节的存储空间,并且extern表明他在其他文件定义,于是编译器就去工程文件中找啊找
终于在file1.c文件中找到了一个table,于是就把table里边前4个字节的值拿出来当做地址使用,这结果为什么这么牵强的?想不懂!
②在file1.c中table是一个数组,实际大小为20字节
(5)定义为指针声明为数组
file1.c

#include <stdio.h>
char *pointer="ABCDEF";
void Display_PointerAddr(void)
{
	printf("file1:*(pointer+1) = %c\n",*(pointer+1));
	printf("file1:pointer_addr = 0x%x\n",p);
}
file2.c
#include <stdio.h>
extern char pointer[];
extern void Display_PointerAddr(void);
int main()
{
	Display_PointerAddr();	
	printf("file2:pointer[0] = 0x%x\n",pointer[0]); 
	printf("file2:pointer[1] = 0x%x\n",pointer[1]); 
	printf("file2:pointer[2] = 0x%x\n",pointer[2]); 
	return 0;
}
运行结果:
file1:*(pointer+1) = B
file1:pointer_addr = 0x422064
file2:pointer[0] = 0x64
file2:pointer[1] = 0x20
file2:pointer[2] = 0x42
Press any key to continue
结果分析:
在file2.c中编译器把file1.c中的char型指针变量pointer当做是长度为4字节的char型数组,file1.c中pointer存放的是地址内容,于是file1.c中就把这个地址内容当做数组的值来使用了。究竟为什么会这样做,实在不懂其中的原理,只能通过这种现象来记住这种结论。

(4)和(5)编程小结:以后遇到这两种情况时千万不要定义了数组和指针中的一种,然后在另外的文件中extern声明为另外一种类型

(6)变量用作右值时,编译器只取其变量值,不关心类型,但有些隐式类型转换会有warming
(7)指针变量用作数组名时,下标为负号的问题
int tab[5];
int *p=&a+1;
p[-1]会被编译器解释成*(p-1),也就指向了tab[4]
(8)结构体成员是“指针”时一定要记得先初始化让他有个明确的指向后才能进行“赋值”操作!!!对于指针变量在定义时如果还不知道其指向最好用NULL拴住他,免得成为野指针!
(9)char *p=(char *)malloc(0);malloc函数返回的内存里边的一个地址,不是NULL,但是这个地址是不能用的。这好比尺子上的某个刻度,刻度本身并没有长度,只有某两个刻度一起才能量出长度。
(10)free(p)之后p的指向并没有发生改变,指向的内容也没有改变。在visual c++6.0中free之后的这个指针变量任然可以拿来使用,
看个例子:

#include <stdio.h>
#include <stdlib.h>
void my_mallloc(void)
{
	char *p2 = (char *)malloc(1);
	printf("\nafter free p1--in my_malloc:\np2=%d\n",p2);
	printf("(*p2) = %d\n\n",*p2);
}
int main()
{
	char *p1=(char *)malloc(1);
	printf("\nbefore free p1:\np1=%d\n\n",p1);
	free(p1);
	*p1 = 123;
	printf("after free p1:\n(*p1) = %d\n",*p1);
	printf("p1 = %d\n",p1);

	my_mallloc();
	
	return 0;
}
运行结果:
before free p1:
p1=8266296

after free p1:
(*p1) = 123
p1 = 8266296

after free p1--in my_malloc:
p2=8266296
(*p2) = -51

Press any key to continue
结果分析:从运行的结果分析可知,在my_malloc函数中定义的指针变量p2和main里边的p1指向是一样的。只是从编程的逻辑上不允许这样做,因为你既然都要free他就是之后不要用到这个内存的意思,之后为了防止吴用free(p1)之后也要将p1用NULL来拴住。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值