标签:c
转载请标明出处:http://blog.csdn.net/u012637501
内存的存储是以一个字节为一个编号,也就是8位合在一起给一个编号,不是0,1就给编号。 内存分为很多个单元,每个单元就会分配一个编号。
指针核心:
(1)数据类型 * 变量名:* 表示该变量为指针变量,存放的是(数据类型)变量的 存储地址,如int
*p=&i;
(2)* 指针变量:*表示指向"以指针变量的内容为存储地址的 变量",如*p=i;
一、指针概念
1.地址:地址就是内存单元的一个编号,从0开始的非负整数,范围为0~FFFFFFFFF(0~4G-1).CPU对内存是通过控制、数据、地址三条总线来进行控制的。
◆控制:cup会先把内存中的数据读入,进行处理后,在返回给内存,然后内存在把数据写入硬盘。
◆数据:用于数据的传输,不管是把内存中的数据发送给cpu,还是把cpu的数据写如内存条,都是由数据线来完成的,但是数据传输的方向则是由控制线来控制的。
◆地址:地址线则是确定数据要写入内存中的那个单元,所谓的一个单元就是一个字节。
一条地址总线能控制2的1次方,一般的机器有32个地址线,最终能够控制2的32个单元,而每个单元是八位,而最终我们的内存能够存储2的32次方*8位。 则换算为G的话,最终大小为4G.那么地址总线的范围则是4G大。
2.指针:指针就是地址,地址就是指针。指针的本质是,一个操作受限的非负整数。
指针的重要性:
◇通过指针表示一些复杂的数据结构;
◇指针实现快速传递数据,减少了内存的耗用;
◇使函数返回一个以上的值;
◇指针能够直接访问硬件,且方便处理字符串。
3." * "的作用
(1)定义指针变量:如int *p;,即定义了一个名字叫p的变量(称指针变量),int *表示只能存放int类型变量的地址;
(2)指针运算符:该运算符放在已经定义好的指针变量的前面,如果p是一个已经定义好的指针变量,则*p表示以p的内容为地址的变量,如*p=i,*p代表的是p所指向的那个变量i。
4.指针变量:同样是一个变量,但是指针变量存放其他变量的地址。
§举例1:int * p;
int i=10,j;
p=&i;
j=*p;结果:j=10。
详解:(1)如果去掉"p=&i",那么指针变量p存放的地址是随意的。
(2)int * p:p是变量的名字,int
*表示p变量存放的int类型变量的地址。int * p即p是变量
名,p变量的数据类型是int *类型,所谓"int
*类型"实际就是存放int变量地址的类型。
(3)p=&i:指针变量p保存了i的地址,指针变量p指向了普通变量i,则 *p=i,*p就是以p的内容
为地址的变量。修改p的值不影响i的值,修改i的值也不会影响p的值
§举例2:int i=10;
int * p=&i; 即等价于 int * p; p=&i;
详解: int * p=&i,即指针变量p保存的是int类型变量的地址。
注意:指针与指针变量是两个不同的概念,指针的本质就是一个操作受限的非负整数。
§举例3:
#include<stdio.h>
int main(void)
{
int *p,*q;
int i=10;
p=&i; //如果*p=i,则编译通过但运行出错,只能int *p=&i;或者 int * p; p=&i;
*p=q; //类型不同,语法错误
// *p=*q; //编译通过,运行出错,因为q没有赋值。
//p=q; //编译通过,运行出错,因为q是垃圾值赋值给p,p也变成垃圾值
printf("%d\n",*p);
// print("%d\n",*q);//编译通过,运行出错
return 0;
}
详解:(1)*q代表的是整形,因为*q代表的是以q的地址为内容的变量。而p是地址(int *)类型。
(2)打印*q时出错。因为q的空间是属于本程序的,所以本程序可以读写q的内容(地址)。但是如果q内部是垃圾值(未知地址),则本程序不能读写*q的内容(变量的值),因为此时*q所代表的内存单元的控制权限并没有分配给本程序,所以本程序运行print("%d\n",*q);时就会立即出错。
5.如何通过被调函数修改主调函数中普通变量的值?
(1)实参为相关变量的地址;
(2)形参为该变量的类型为类型的指针变量;
(3)在被调函数中通过" *形参变量名 " 的方式就可以修改主函数中变量的值。
注:
一旦函数执行完毕,其内部的形参所占空间就被收回。
§举例1:通过指针在子函数中修改主函数变量的值
#include<stdio.h>
void f(int * p)
{
*p=100;
}
int main(void)
{
intt i=9;
f(&i);
printf("i=%d\n",i);
return 0;
}
运行结果:i=100
说明:
(1)f(int *p),不是定义了一个名字叫做*p的形参,而是定义了一个形参,该形参名字叫做i,它的类型是int *,即int * p意味变量p存放的是整型变量地址;
(2)*p=100,由于函数实参为&i(地址),*p=i;
§举例2:若指针指向的变量值互换
/*指针互换程序*/
#include<stdio.h>
void exchange(int *p,int *q)
{
int temp;
temp=*p;
*p=*q;
*q=temp;
}
void main()
{
int a=5,b=7;
exchange(&a,&b);
printf("a=%d,b=%d",a,b);
while(1);
}
运行结果:a=7,b=5
说明分析:
(1)由于exchange()函数形参为int *类型的指针变量(存储地址),因此实参传入的是int类型变量
的地址。
(2)对于临时变量temp,如果要互换*p和*q的值(为值),则t必须定义成int temp,而不能定义成int
*temp。因为int *为指针变量的类型,其值为地址。
(3)值交换内存分析
§举例3:若指针变量保存的地址互换
/*指针互换程序*/
#include<stdio.h>
void exchange(int *p,int *q)
{
int *temp;
temp=p;
p=q;
q=temp;
}
void main()
{
int a=5,b=7;
exchange(&a,&b);
printf("a=%d,b=%d",a,b);
while(1);
}
运行结果:a=5,b=7
说明分析:
(1)对于临时变量temp,如果要交换指针变量q和p的值,则temp必须为int *类型,而不能用int。因
为,int *表示的是地址类型,int表示的是变量值类型。
(2)交换指针变量q和p,则是交换指针变量所保存的值,只影响指针变量p、q指向的内存地址变
化,而不影响该内存地址所保存的值。
(3)内存分析
☆区别:指针与指针变量
◆指针就是地址,地址就是指针。地址就是内存单元的编号。
◆指针变量:存放地址的变量。而指针只是一个值,这个值是内存单元的一个编号。指针变量才是一个变量,他里面才可以存放数据。
◆指针和指针变量是两个不同的概念,但是需要注意的是,通常我们在叙述时会把指针变量简称为指针,实际他们含义并不一样。
二、指针和数组
1.数组名
一维数组名是个指针变量,它存放的是一维数组第一个元素的地址。它的值不能被改变,一维数组名指向的是数组的第一个元素。即数组名a=&a[0],是一个常量(地址值),常量是不能被改变的,即一维数组名是不能被 改变的。
2.下标与指针关系
a[i] <<==>>*(a+i)
假设指针变量的名字为p,则p+i的值是p+i*(p所指向的变量所占的字节数)。
3.指针变量的运算原则
(1)指针遍历不能相加,不能相乘,不能相除;
(2)如果两指针变量属于同一数组,则可以相减。或者说两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才可以相减;
(3)指针变量可以加减一整数
如:p+i的值是p+i*(p所指向的变量所占的字节数)
p-i的值是p-i*(p所指向的变量所占的字节数)
p++ <===>p+1
p-- <===>p-1
§举例1:如何通过被调函数修改主调函数中一维数组中的内容?
#include<stdio.h>
show_array(int * p,int len)
{
int i;
for(i=0;i<len;i++)
printf(" %d",*(p+i)); //等价于p[i]
}
int main(void)
{
int a[]={1,2,3,4,5};
show_array(a,5); //实参为数组第一个元素地址、数组长度
return 0;
}
运行结果:1 2 3 4 5
分析说明:
(1)数组名a等价于&a[0],&a[0]本身就是int *类型;
(2)p[i]=*(p+i)=*(a+i)=a(i),即p(i)就是主函数的a[i]
(3)内存分析
§举例2:计算指针变量所占字节数
#include<stdio.h>
int main(void)
{
double *q;
double arr[3]={1.1,2.2,3.3};
q=&arr[0]; //将数组的第一个元素地址赋值给类型为double *的指针变量
printf("%p\n",q);
q=&arr[1];
printf("%p\n",q);
return 0;
}
运算结果:
0000 FFAC
0000 FFB4
分析说明:
(1)%p的作用是输出变量地址(存放至内存的起始地址),
(2)qarr[0]占8个字节,1个字节8位且一个字节在内存中就是一个地址。由B4-AC=8,即证明数据的每一个元素在内存中占8个字节。如果数据类型为char,则结果为C1-C0=1,数组的每一个元素在内存中占1个字节。
总结:
★无论指针变量指向的变量占多少字节,所有的指针变量只占4个字节,且用第一个个字节的地址表示所指向的整个变量的地址。原因:*p具体指向几个字节,要靠前面类型确定,如果为int则为4字节,如果double则占8字节。CPU
与 内存交互时 有32根线,每根线只能是1或0两个状态,所有总共有232个状态。 1 个状态 对应 一个单元。如全为0 全为1 等。 内存中第一个单元,即32根线状态全为0。
0000 0000 0000 0000 0000 0000 0000 0000 ,其大小为4字节
(1字节=8位),所有每个地址(硬件所能访问)的用4个字节保存(而不是一 位bit) 。一个变量的地址—用该变量首字节的地址表示。这也就是为什么指针变量始终只占4字节的原因。
★一个变量的地址,是用该变量首字节的地址来表示。
4.疯狂指针-壹
标签:c
原文地址:http://blog.csdn.net/u012637501/article/details/45269469