第七章指针

你好!我是小柒,今天咋们一起来学习一下指针。

指针

本节内容

1、指针变量的定义
2、取地址运算符&
3、取数值运算符
4、指针的算术运算
5、指针与数组
6、指针与字符串
7、指针做为函数参数

 

引言:

假设你想打电话订餐,你拿起电话:“我要订一份宫保鸡丁盖饭”,然后咔嚓一下你把电话撂了,会是什么结果。人家还得给你打回来,问:“SB你住哪儿啊”。

(你没说地址人家怎么给你送,所以我们计算机要访问内存并存取数据也要有内存的地址才能访问。)

 

小柒变量是什么?

答:变量是容器,整型变量是存放整型数据的容器,char型变量是存放char数据的容器,指针变量是什么容器?是存放内存地址的容器

 

小柒什么指针?

答:C语言指针的作用很多,其实说白了就是直接操作内存

 

小柒什么是内存? 

答:内存地址也是一种数据,也要占一定的内存空间

 

小柒那么内存地址占多大空间呢?

答:这要看操作系统的位数而定,32位系统内存地址点32bits,也就是4个字节,64系统内存地址占64bits,也就是8个字节。 内存地址本身没有差异,具体怎么存取,取决于你用什么类型的指针去访问。

 

1、指针变量的定义

小柒什么是指针变量?

答:指针变量就是存放地址( 内存编号)的变量。

指针变量的定义很简单,就是在定义变量的时候在变量前面加上一个*号就可以了

格式:类型修饰符 *变量名 = 初始值;

        int *p = NULL;

       此时的*只起到修饰作用,告诉编译器,p是个指针。

        NULL恒等于0

        输出用%p表示

如上,p就是一个指向int型数据的指针,那么这个int型指针变量占多大内存空间呢,我们用sizeof()测试一下就知道了.

示例

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int *p = NULL;

    printf("%ld\n",sizeof(p));

    

return 0;

 

}

打印结果:8

说明这台电脑是64位操作系统,大家可以试试其他不同类型的指针变量占用多大内存空间

 

2、取地址运算符&

回顾;其实咱们很早以前讲scanf()时就用到了取地址符.

小柒如何能取到变量的地址的呢,使用&运算符

#include <stdio.h>

int main(int argc, const char * argv[]) {

    int *p = NULL;//空指针

    int a = 3;

    p = &a;//a的地址赋值给p

//   取地址

    printf("p = %p\n",p);

    printf("&a =%p\n",&a);

return 0;

}

打印结果:

p = 0x7fff5fbff804

&a =0x7fff5fbff804

小柒分析:可以看到指针变量p保存的值就是从变量a取出的地址,指针变量跟其他变量一样,定义后要给一定的初值,一般指针变量赋初值都是给NULL(一个宏),就是空指针,其实就是整型的0x0。

 

3、取数值运算符

#include <stdio.h>

int main(int argc, const char * argv[]) {

    int *p = NULL;

    int a = 3;

    p = &a;

//   取数值

    printf("a = %d\n",a);

    printf("*p = %d\n",*p);

return 0;

}

打印结果:

a = 3

*p= 3

小柒分析:当指针变量p保存了变量a的地址后,通过*p就可以获取变量a中的内容。

 

4、指针的算术运算

 示例

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int *p = NULL;

    int a = 3;

    p = &a;

//   算术运算

//   指针地址减1时,地址向低地址跳转4个字节

    printf("p - 1 = %p\n",p - 1);

//   原指针地址

    printf("p     = %p\n",p);

//   指针地址加1时,地址增加了4个字节

    printf("p + 1 = %p\n",p + 1);

 

return 0;

 

}

打印结果:

p - 1   =  0x7fff5fbff800    //   指针地址减1时,地址向低地址跳转4个字节

p        =  0x7fff5fbff804   //   原指针地址

p + 1 =  0x7fff5fbff808  //   指针地址加1时,地址增加了4个字节

 

5、指针与数组

数组是一块连续均匀分配的内存空间,数组名是常量地址,指针可以保存数组的首地址,通过指针自增来访问数组,实际数组的下标访问就是通过指针自增来访问的。通过指针访问数组和通过数组访问数组从实现效果上是一样的,但其实还是有些差异的,通过数组名访问是地址直接增加,而通过指针来访问要先把地址从指针变量里取出来再增加,成本高一点。

指针访问数组的方法:

1)

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int array[] = {1,2,3,4,5,6};

    int *p = array;

//   遍历

    for (int i = 0; i < 6; i++) {

        printf("%d\n",p[i]);

    }

return 0;

 

}

打印结果:

1

2

3

4

5

6

 

2)

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int array[] = {1,2,3,4,5,6};

    int *p = array;

    //   遍历

    for (int i = 0; i < 6; i++) {

        printf("%d\n",*(p + i));

    }

    

return 0;

 

}

打印结果:

1

2

3

4

5

6

 

3)

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int array[] = {1,2,3,4,5,6};

    int *p = array;

    //   遍历

    for (int i = 0; i < 6; i++) {

        printf("%d\n",*(p++));

    }

    

return 0;

 

}

打印结果:

1

2

3

4

5

6

 

4)

#include <stdio.h>

int main(int argc, const char * argv[]) {

    

    int array[] = {1,2,3,4,5,6};

//   遍历

    for (int *p = &array[0] ; p < &array[6]; p++){

        printf("%d\n",*p);

    }

return 0;

 

}

打印结果:

1

2

3

4

5

6

 

6、指针与字符串

示例 

//字符串指针指向字符串

#include <stdio.h>

int main(int argc, const char * argv[]) {

    char c;

//    表示p是一个指向字符变量c的指针变量

   char *p = &c;

//     表示s是指向字符串的指针变量。把字符串的首地址赋给s

    char *s = "C Language";

    

    return 0;

}

 

示例

//字符串指针指向字符串

#include <stdio.h>

 

int main(int argc, const char * argv[]) {

//    创建一个字符串

   char *string = "I Love China!";

//    等效与

    char *string1;

    string1 ="I Love China!";

    printf("string = %s\n",string);

    printf("string1= %s\n",string1);

    return 0;

}

打印结果:

string1= I Love China!

string = I Love China!

 

7、指针做为函数参数

示例交换两个数的值

#include <stdio.h>

void swap(int m,int n);

int main(int argc, const char * argv[]) {

    int a = 3,b = 5;

    swap(a, b);

    printf("a = %d,b = %d\n",a,b);

    return 0;

}

void swap(int m,int n){

    int c;

    c = m;

    m = n;

    n = c;

    printf("m = %d,n = %d\n",m,n);

}

打印结果:

m = 5,n = 3

a = 3,b = 5

//主函数的a和b没有交换,这是因为当a和b的值传递给形参m和n,在swap函数中只是对形参m和n的值进行了交换,而实际参数并没有被影响到!

 

用指针修改问题

#include <stdio.h>

void swap(int *m,int *n);

int main(int argc, const char * argv[]) {

    int a = 3,b = 5;

    int *p1 = &a,*p2 = &b;

    swap(p1, p2);

    printf("a = %d,b = %d\n",a,b);

    return 0;

}

void swap(int *m,int *n){

    int c;

    c = *m;

    *m = *n;

    *n = c;

    printf("m = %d,n = %d\n",*m,*n);

}

//本例中函数的参数是指针,也就是说传递给swap函数的是a和b在内存中的地址(不是他的值),这样swap函数进行操作时,形参m,n和实参*p1和*p2指向的都是a和b,在swap函数内部交换了*m和*n的值,也就相当于交换了*p1和*p2的值,结果主函数中a和b的值交换了。

 

指针的全部课程就结束了,希望大家好好敲代码,记得预习宏定义,typedef,结构体,枚举,小柒在这给大家加油了。

posted on 2015-12-27 14:53  xxQMYxx  阅读(198)  评论(0)    收藏  举报

导航