结合内存存储数据的机制,c语言里指针的出现和使用也就不奇怪了,如果先学了内存的一些知识,以及程序运行机制,到了c指针这块就会清晰很多。
#include <stdio.h>
int main(void){
int a = 180;
int b = 156;
int *c = &a; // int 指数据类型 * 指这是一个指针变量,存的是地址,&a是 a变量的地址, 把a的地址存在c这个指针变量类型里。
*c = 190 ; // 这里c里已经存上一个地址数据了,*c操作的是指向 c里的地址指向的数据也就是a内存空间里的数据
// 这样就像是间接操作一样,操作了a的数据
printf("%d",a); //输出a会变成190
return 0;
}
另外在函数传递参数的时候会看到诸如 void functionname(int arr[]) ;这里的arr[] ,[]里没有值指的是数组 arr第一个元素的地址,也就是 &arr[0] ,这就是为什么数组操作函数在函数里面操作了这个数组的话,外面调用的这个数组数据也已经变了,因为这里是传递一个指针,函数内和函数外这个参数是同一个内存空间上的数据。
再比如scanf("%d",&a); 这种函数传递参数时要用到参数地址,明白了上面的道理就知道为什么要加&号了。
但是还有一种情况 如果是scanf 字符串 ,例如 scanf("%s",str); 这里str 本身就是字符数组,传递进来就是指针,所以也是引用操作
再来看看数组和指针的一个简单例子
#include <stdio.h>
int main(void)
{
int a[3]={1,2,3};
int *p=&a[0]; //把a数组第一个元素的地址赋值给p指针
int i;
for(i=0;i<3;i++){
printf("a[%d] = %d ",*(p+i)); //由于数组的内存地址是连续的,这时候P的地址依次递增,再加上*指针操作就会 依次操作a[0] ,a[1],a[2]
// *(p+0) -> a[0] *(p+1) -> a[1] *(p+2) -> a[2]
}
p=&a[1]; // 注意理解下 p=&a[1] 不能写成 *p=&a[1] ;
printf("a[0] is %d",*(p-1)); // *(p-1) 指 a[0]
printf("a[2] is %d",*(p+1)); // *(p+1) 指 a[2]
//注意以下区别
int *p=&a[0]; //相当于双重定义 整形的指针 p, 也可以写出 int *p; p=&a[0];
p=&a[1]; // 对
*p=&a[1]; // 错
*p=56; // 对
return 0;
}