标签:
1 int i=3; 2 int* p=&i; 3 int*pp; pp=&i; 4 int* ppp; *ppp=i;
指针:
本质上也是变量;需要占用内存空间;存储另一个变量的地址值
不同类型的指针:(int* char* long*)
不同类型的指针,它本身所占内存大小(var_name)是相同的,不过它指向的内存空间大小(*var_name)不一样。由于指针变量存储的是内存地址,所以对于32位机上,指针变量应该占用32位。
*:
在指针声明时,*表示声明的变量为指针
在指针使用时,*表示指针所指向的内存空间中的值
传值调用与传址调用:
当一个函数体内部需要改变实际参数的值,则需要指针参数
函数调用时,实际参数的值复制到形式参数的空间,值有两种情况的取值:实际的值,地址值:
1 struct test 2 { 3 int a[10000]; 4 char b[100000]; 5 }; 6 void ff(struct test tt) 7 { 8 for(int i;i<10000;i++) 9 tt.a[i]=0; 10 } 11 int main() 12 {
13 ff(ss); 14 return 0; 15 }
此时传值调用,这将复制大量的数据,而传址调用,只会复制一次。
数组:
数组是相同类型的变量的有序集合。
int a[5];
a代表这个有序集合的起始地址,第一个元素的地址,即:
a=&a[0],
a+1=&a[1]
a[3]=*(a+3)
a是一个常量指针,在表达式中只能作为右值使用,只能在以下情况下不能看作是常量指针:
sizeof(a) //表示整个数组的长度
&a //a=&a
分配了5个int型的内存空间——a[0]-a[4]
数组空间大小:sizeof(int)*5=sizeof(a)
数组元素的个数可以显式或隐式之指定:
int a[5]={5,2};//a[0]=5,a[1]=2;a[2],a[3],a[4]均为0
int b[]={1,2}; //只分配两个int型空间:b[0]=1,b[1]=2
int c[5]={0}; //将所有变量赋值为0
当初始化列表小于变量个数,剩余的变量以0进行初始化;如果变量不进行初始化,那么将分别是随机值
a与&a的区别:
a代表数组的首元素地址,&a表示整个数组的地址,a=&a
a+1=&a[1]
&a+1表示整个数组空间所占内存空间的下一个空间地址
1 int a[5]={0}; 2 p=a; 3 p+1; 4 a+1;
1 #include <stdio.h> 2 int main() 3 { 4 int a[5] = {1, 2, 3, 4, 5}; 5 int* p1 = (int*)(&a + 1); 6 int* p2 = (int*)((int)a + 1); 7 int* p3 = (int*)(a + 1); 8 printf("%d, %d, %d\n", p1[-1], p2[0], p3[1]); 9 return 0; 10 } 11 12 // p1[-1]==>*[p1-1];a[3]=*[a+3] 13 //a+1区别于(int)a+1,因为每个字节对应一个地址,那么(int)a+1表示的是第一个数组变量的第二个字节的地址,a=(int)a, 14 //a+1表示第二个数组变量的地址
c语言中,数组作为函数参数时,编译器将其编译成对应的指针:
1 void func(int a[]);-->void func(int* a);
2 void func(int a[4]);-->void func(int* a); //调用时并不执行int a[4]
一般情况下,当定义的函数中有数组参数时,需要另一个参数标识数组的长度。
标签:
原文地址:http://www.cnblogs.com/data1213/p/4823481.html