sizeof()
- 是一个运算符,给出某个类型或变量在内存中所占据的字节数
-
sizeof(int)
返回4,占据4个字节,一个字节是8bit,所以这是32位 -
sizeof(i)
返回4 -
sizeof(double)
返回8#include <stdio.h> int main(){ int a; a = 6; printf("sizeof(int)=%ld\n", sizeof(int)); printf("sizeof(a)=%ld\n", sizeof(a)); printf("sizeof(double)=%ld\n", sizeof(double)); return 0; }
-
运算符&
-
scanf("%d", &i);
里的& - 获取变量的地址,它的操作数必须是变量
int i; printf("%x",&i);
- 地址的大小,是否与int相同,取决于编译器的架构,是32位还是64位
int i; printf("%p",&i);
- &不能对没有地址的东西取地址:&(a+b),&(a++)
- 相邻变量的地址:相差4个字节,并且是先定义的在高位,这是因为C语言内存用的stack堆栈,分配内存给变量是自顶向下的.
- 取数组的地址,可以看到,&a=a=&a[0],和a[1]相差4字节:
int a[10]; printf("%p\n", &a); printf("%p\n", a);\ printf("%p\n", &a[0]); printf("%p\n", &a[1]);
scanf()
- 如果能够将取得的变量地址传递给一个函数,能否通过这个地址在那个函数内访问这个变量?
scanf("%d", &i);
- scanf()的原型应该是怎样的?我们需要一个参数能保存别的变量地址,如何表达能够保存地址的变量?
指针
就是保存地址的变量
- 通常用p(point)来作为变量名
int i;
int* p = &i;
加*号表示p是一个指针,用来保存变量i的地址
int* p,q;
这里p是指针,而q只是普通int变量
int *p,q;
*号靠近int和靠近p,都同样表明p是指针 - 指针变量的值: 是具有实际值的变量的地址
- 作为参数的指针
void f(int *p);
- 在被调用的时候得到了某个变量的地址:
int i = 0; f(&i);
- 在函数里面可以通过这个指针访问外面的这个i,并且还能通过指针修改外部的i值
void f(int *p); //函数申明 int main(void){ int i = 6; f(&i); //调用f函数,把i的地址作为参数传入 return 0; } void f(int *p){ printf("p=%p\n", p); //打印地址 printf("*p=%d\n", *p); //可以将*p看成一个完整的值,这个值也是p地址中保存的i的值 *p = 26; //这样就可以通过指针来修改i的值 }
- 传入函数的数组其实是指针
void minmax(int a[], int len, int *max, int *min); int main(void){ int a[] = {1,2,3,4,5,6}; int min,max; printf("main sizeof(a)=%lu\n", sizeof(a)); //这里的数组a[]长度应该是24(6个元素) //调用minmax函数,传入四个参数:数组a[],sizeof(a)/sizeof(a[0])是元素个数,*min和*max是指针值 minmax(a, sizeof(a)/sizeof(a[0]), &min, &max); printf("min=%d,max=%d\n", min, max); return 0; } void minmax(int a[], int len, int *min, int *max){ int i; //下面输出的数组a[]的长度是4,说明传进来的数组是一个指针. printf("minmax sizeof(a)=%lu\n", sizeof(a)); *min = *max = a[0]; for (i=1; i<len; i++){ if (a[i] < *min){ *min = a[i]; } if (a[i] > *max){ *max = a[i]; } } }
- 所以
void minmax(int a[], int len, int *min, int *max)
中的int a[]
可以替换为int *a
- 以下四种函数原型是等价的:
int sum(int *ar, int n);
int sum(int *, int );
int sum(int ar[], int n);
int sum(int [], int);
数组变量是特殊的指针
- 数组变量本身表达地址,所以:
-
int a[10]; int *p = a;
//无需用&取地址 - 但是数组的单元表达的是变量,需要用&取地址
-
a == &a[0]
数组a的地址等于a[0]的地址
-
- []运算符可以对数组做,也可以对指针做:
-
p[0] <==> a[0]
对于指针p来说,它可以像数组一样调用p[0],即使它所指向的变量值只有一个.
-
- *运算符可以对指针做,也可以对数组做:
*a = a[0]
- 数组变量是const(常量)的指针,所以不能被赋值:
-
int a[]
<==>int * const a = ...
-