设为首页 加入收藏

TOP

C语言入门-指针(一)
2019-10-09 19:52:15 】 浏览:96
Tags:语言 入门 指针

终于到了精髓的地方了,这确实有点懵,总感觉这太麻烦了,而且写着也不爽,还是怀念py或者java,但也没办法,还是要继续学下去。

一、运算符&

  1. scanf("%d" , &i); 里的&
  2. 获取变量的地址,它的操作数必须是变量
  3. 地址的大小是否与int相同取决于编译器
#include <stdio.h>
int main(void)
{
    int i = 0;
    printf("0x%x\n", &i);
    // 0x62fe4c
    return 0;
}

&不能取的地址

&不能对没有地址的东西取地址

  1. &(a+b) ?
  2. &(a++) ?

二、指针

  1. 如果能够将获得变量的地址传递个一个函数,能否通过这个地址在那个函数内访问这个变量?
  2. scanf("%d" , &i);
  3. scanf()的原型应该是怎样的?我们需要一个参数保存别的变量的地址,如何表达能够保存地址的变量

指针

就是保存地址的变量 , *p

// p是一个指针,现在把i的地址交给了p
int i;
int* p = &i;

// 下面两种形式一样,p是一个指针,而q是一个普通的int变量
int* p , q;
int *p , q;

指针变量

  1. 变量的值是内存的地址
  2. 普通变量的值是实际的值
  3. 指针变量的值是具有实际值的变量的地址

作为参数的指针

  1. void f(int *p);
  2. 在被调用的时候得到了某个变量的地址
  3. int i = 0;f(&i);
  4. 在函数里面可以通过这个指针访问到外面的的这个i
#include <stdio.h>

void f(int *p);

int main(void)
{
    int i = 6;
    printf("&i=%p\n", &i);
    f(&i);

    return 0;
}

void f(int *p)
{
    printf(" p=%p\n", p);
}

// 可以看到这里获取的地址是相同的
// &i=000000000062FE4C
//  p=000000000062FE4C

访问那个地址上的变量*

  1. *是一个单目运算符,用来访问指针的值所表示的地址上的变量
  2. 可以是右值也可以是左值
  3. int k = *p;
  4. *p = k + 1;

*左值之所以叫左值

  1. 是因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果
  2. a[0] = 2;
  3. *p = 3;
  4. 是特殊的值,所以叫左值
#include <stdio.h>

// 声明两个函数
void f(int *p);
void g(int k);


int main(void)
{
    int i = 6;
    printf("&i=%p\n", &i);
    f(&i);
    
    // 此时i的值已经发生了变化
    g(i);

    return 0;
}


// 传入的是地址
void f(int *p)
{
    printf(" p=%p\n", p);
    printf("*p=%d\n", *p);
    *p = 66;
}

// 传入的普通int
void g(int k){
    printf("k=%d\n", k);
}


// &i=000000000062FE4C
//  p=000000000062FE4C
// *p=6
// k=66

三、指针的使用

指针应用场景一

交换两个变量的值

#include <stdio.h>

void swap(int *pa , int *pb);

int main()
{
    int a = 5;
    int b = 10;
    swap(&a , &b);
    printf("a=%d , b=%d\n", a , b);
    return 0;
}

void swap(int *pa , int *pb){
    int t = *pa;
    *pa = *pb;
    *pb = t;
}

指针应用场景二

  1. 函数返回多个值,某些值就只能通过指针返回
  2. 传入的参数实际上是需要保存带回的结果的变量
#include <stdio.h>

void minmax(int a[] , int len , int *min , int *max);

int main(void)
{
    int a[] = {1,2,3,4,5,6,7,8,9,12,13,14,15,34,35,66,};
    int 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;
    *min = *max = a[0];
    for (i = 0; i < len; i++)
    {
        if (a[i] > *max)
        {
            *max = a[i];
        }
        if (a[i] < *min)
        {
            *min = a[i];
        }
    }
}

指针应用场景二b

  1. 函数返回运算的状态,结果通过指针返回
  2. 常用的套路是让函数返回特殊的不属于有效范围内的值表示出错
    • -1 或 0
  3. 但是当任何数值都是有效的可能结果时,就得分开返回了
#include <stdio.h>

// 如果成功就返回1,否则就是0
int divide(int a , int b , int *result);

int main(void)
{
    int a = 5;
    int b = 2;
    int c;
    if (divide(a,b,&c))
    {
        printf("%d/%d = %d\n", a, b, c);
    }

    return 0;
}

int divide(int a , int b , int *result)
{
    int ret = 1;
    if ( b== 0)
    {
        ret = 0;
    }else{
        *result = a/b;
    }

    return ret;
}

指针常见的错误

定义了指针变量,还没有指向任何变量,就开始使用了

四、指针与数组

传入函数的数组成什么了?

  1. 函数参数表中的数组实际上是指针
  2. sizeof(a) == sizeof(int*)
  3. 但是可以用数组的运算符[]进行运算

下面的四种函数原型是等价的

int sum(int *ar , int n);
int sum(int* , int);
int sum(int ar[] , int n);
int sum(int[] , int);

数组变量是特殊的指针

数组变量本身表达地址,所以

  1. int a[10]; int*p = a; // 无需用&取地址
  2. 但是数组的单元表达的是变量,需要用&取地址
  3. a == &a[0]

[]运算符可以对数组做,也可以对指针做

  1. p[0] <===> a[0]

*运算符可以对指针做,也可以对数组做

  1. *a = 25

数组变量是const的指针,所以不能被赋值

五、指针与const

  1. 表示一旦得到了某个变量的地址,不能再指向其他变量
    // q内写的地址不能被改变
    int *const q = &i
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇数据结构--排序 下一篇C语言入门-字符串

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目