登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] 更多使用指针的细节

[复制链接]
发表于 2018-2-4 19:19:29 | 显示全部楼层 |阅读模式
学习笔记
学习科目: C语言,数组,指针
学习安排: 明天结束
开始时间: 2018-02-04
结束时间:
& 取址运算符
* 是指针变量的类型
指针就是指向一个变量或常量的地址,这是他的本质

int* p,q;
此时p是指针,q是整数
想要q也是指针就必须
int *p,*q;

*和&可以相消
*&p指的就是p
可以看做*(&p),先对p取地址,*(地址)表示这个地址表示的值
int *p=&a;
p=(a的地址); *p=a;

数组和指针

如果我们定义一个指针
int *p;
int a[15];
p=a;
这里会有一个隐性转型,将数组转化为数组第一个单元的地址
即:p=&a[0];

如果,我们强行读取数组a[15]的地址,会是什么结果?
printf("%p",a);
上面这个述句我们得到的就会是a[0]的地址

通过上面这两个例子,我们可以得到指针和数组是由非常密切的联系的
实际上,数组是一种const指针
int*const p,这个指针是不可以修改的,只能指向定义数组时产生的位置
其实数组和指针的关系可以通过这个式子表示
a[b]=*(a+b);
即:若p=a[0];
那么 p+1=a[1];
那指针加一又有什么意义呢?
指针加一,加的其实是一个sizeof(所定义的指针类型)

记得在函数中使用数组吗
我们举一个简单的例子
#include<stdio.h>
void f(int a[],int n);

int main()
{
    int n[]={1,2,3,4,5,6,7,8,9,10,};
    f(n);
    return 0;
}
void f(int a[],int n){
    int i;
    for(i=0;i<n;i++){
        printf("%d",a[i]);
    }
}
我们在函数中传递的数组是什么?
其实就是一个const指针,是一种只能指向这个数组的指针
如果我们通过这个函数对这个数组进行修改,结果是真的会改动数组的值
所以我们在将数组作为一个值传入函数时,函数名后数组的方括号中填了数组也与数组大小无关
甚至我们还可以这样写
void f(int *a,int n){
    int i;
    for(i=0;i<n;i++){
        printf("%d",a[i]);//这里的a[i]其实就是*(a+i)
    }
}

数组还有一个特性
a[3]-a[1]=2;
也就是说数组单元相减会得到,中间有几个数组单元

前面提到 int *const p是指针不可修改
那 int const*p 和 const int *p又是什么意思?
其实这两种都表示
通过指针不能修改地址内部的值,这个指针可以随意的指向任何地址,但是它不能通过指针不能改变地址内部的值
如:
int i=7;
int const *p=i;
*p表示的就是 i
但是 *p=9;通过指针修改变量就是不行,这句语句就是错的
i=9;这个就是对的

*p++
表示先取p的地址内的东西,再给p++
在一些操作系统中,*p++是可以加快运行效率的

当然,指针也可以用来大小的比较

0地址
0地址通常是不能随便碰的地址
所以指针不应该具有0值
因此可以用0地址来做一些特殊的事情
    返回的指针是无效的
    指针没有被真正的初始化
NULL是一个预定定义的符号,用来表示0地址
有的编译器不愿意你使用地址的所以一般用NULL就行

指针的类型转换
void* 标傲世不知道指向什么类型的指针
    计算时与char*相同(但是不相通)
指针也可以转化类型
    int*p=&i;
    void*q=(void*)p;
    这时候i还是 int型,但是在转型之后,从 p 看 i 就是一个 void型

指针用来做什么
1.需要传入较大数据的时候作参数的类型
2.传入数组后对数组做操作
3.函数返回不止一个结果的时候
4.需要用函数来修改不止一个变量的时候
5.需要动态申请内存的时候

前四个我们都讲过了
这回我们看看第五个
在c99中我们可以用变量定义数组大小
int a=6;
int n[a];
那c99以前呢
int *a=(int*)malloc(n*sizeof(int));
malloc函数在<stdlib.h>中
我们向系统借了内存,总得有借有还
上衣 malloc还有一个配套的 free()
#include<stdio.h>
#include<stdlib.h>

int main()
{
    int number;
    int* a;
    int i;
    printf("输入数量:");
    scanf("%d",&number);
    a=(int*)malloc(number*sizeof(int));
    for(i=0;i<number;i++){
        scanf("%d",&a[i]);
    }
    for(i=0;i<number;i++){
        printf("%d ",a[i]);
    }
    free(a);
    return 0;

在还的时候需要还给申请来的首地址,就是哪里借的哪里还
如果free(NULL);是没有问题的
所以写指针的好习惯是,定义指针的时候就给它附上初值0
在没有 malloc 空间时 free(p)是没有问题的

如果系统已经没空间了
申请失败会返回0,或者NULL
int main(void)
{
    void *p;
    int cnt = 0;
    while(p=malloc(100*1024*1024)){
        cnt++;
    }
    printf("分配了%d00MB的空间",cnt);
    return 0;
}这个小程序就能看你的电脑能借多少空间给你


好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表