c语言的指针

1、 指针前奏

1. 指针的重要性

指针是C语言中非常重要的数据类型如果你说C语言中除了指针其他你都学得很好那你干脆说没学过C语言

2. 小需求
● void change(int  n)函数调用完毕后,改变实参的值
● 分析:修改实参的值->找到存储空间->地址

 

2、 指针变量的定义
1. 定义的格式
● 类名标识符  *指针变量名;
● int *p;
2. 先定义后赋值
● 简单取值
 1 #include <stdio.h>
 2 int main()
 3 {
 4     int a = 10;
 5     
 6     int *p;
 7     
 8     p = &a;
 9     
10     printf("%d",*p );
11     
12     return 0;
13 }
● 简单改值

*p = 9;

3. 定义的同时赋值

int a = 10;

int *p = &a;

4. 实现修改实参

(*pp) == p

    

    *(*pp) == *p = a

    

    **pp == *p = a = 20

 
5. 注意点
● int *p;   p = 1000;
● int *p;   *p = 100;
● int *p;  *p = &a;  不正确写法
● %p输出指针里面存储的地址值
● 其他指针类型说明,比如float *p;  char *p;
● 不能乱用类型,比如int a = 10;  float *p = &a;
6. 清空指针
● p = 0;
● p = NULL;

 

3、 指针实例  
1. 换值
 1 #include <stdio.h>
 2 void swap(int *v1, int *v2);
 3 
 4 int main()
 5 {
 6     int a2 = 90;
 7     int b2 = 89;
 8     
 9     swap(&a2, &b2);
10     
11     printf("a2=%d, b2=%d
", a2, b2);
12     return 0;
13 }
14     // 完成两个整型变量值的互换
15 void swap(int *v1, int *v2)
16 {
17     int temp = *v1;
18     *v1 = *v2;
19     *v2 = temp;
20 }
2. int sumAndMinus(int a, int b, int *minus)

 

 1 #include <stdio.h>
 2 int sumAndMinus(int n1, int n2, int *n3);
 3 
 4 int main()
 5 {
 6     int a = 10;
 7     int b = 7;
 8     
 9     // 存储和
10     int he;
11     // 存储差
12     int cha;
13     
14     he = sumAndMinus(a, b, &cha);
15     
16     printf("和是%d, 差是%d
", he, cha);
17     
18     return 0;
19 }
20 
21 // 返回值是
22 int sumAndMinus(int n1, int n2, int *n3)
23 {
24     *n3 = n1 - n2;
25     
26     return n1 + n2;
27 }
4、 指针探究
1. 指针变量所占用的存储空间
2. 为何指针变量要分类型? 例如:
 1 #include <stdio.h>
 2 int main()
 3 {
 4     // 0000 0000 0000 0000 0000 0000 0000 0010
 5     int i = 2;
 6     // 0000 0001
 7     char c = 1;
 8     
 9     int *p;
10     p = &c;  
11     printf("c的值是%d
", *p);
12     
13     return 0;
14 }

 int *p=&c; 本应该是char类型的,写成了int类型

Printf(“c的值是%d ”,*p);  打印结果为513,而非1

Printf(“c的值是%d ”,c);  值为1

 因为0000 0001

       0000 0010

   0000 0000

   0000 0000

 -----> 0000 0000 0000 0000 0000 0010 0000 0001 

 

5、 指针与数组
1. 指向一维数组元素的指针  例如:int ages[5] = {1,2,3,4,5};

1)数组元素的访问方式

 int ages[5];

 int *p;

 p = ages;

 1> 数组名[下标]  ages[i]

 2> 指针变量名[下标] p[i]

 3> *(p + i)

2)指针变量+1,地址值究竟加多少,取决于指针的类型

 int *   4

 char *  1

 double * 8

3)void change(int array[])等价于void change(int *array)

   array[2] = *(array+2)

4) 元素的地址:

第一个元素的地址  p      &ages[0]

第二个元素的地址p+1    &ages[1]

第三个元素的地址p+2    &ages[2]

第i个元素的地址  p + i   &ages[i]

  元素的值:

  *p          ages[0]

  *(p+1)   ages[1]

  *(p+2)   ages[2]

2. 用指针遍历一维数组元素  int *p;
                                     p =&ages[0]
 
3. 习题
1> 利用一个指针来接收一个数组,指针变量array指向了数组的首元素
 1 #include <stdio.h>
 2 
 3 void change(int *array)
 4 {
 5     printf("%d
", array[2]);
 6     //printf("%d
", *(array+2));
 7 }
 8 
 9 
10 int main()
11 {
12     // 20个字节
13     int ages[5] = {10, 11, 19, 78, 67};
14     
15     change(ages);
16     
17     return 0;
18 }
6、 指针与字符串
1. 字符串回顾

char s[] = mj;

2. 其他定义字符串的方式

char *s = mj;

或者

char *s;

s = mj;

3. 两种定义方式的区别
● 内存分析
● 画图分析
● 常量和变量字符串的区别
● 常量的内存地址查看

 1.常量区

 存放一些常量字符串

 2.堆

 对象

 3.栈

 存放局部变量

     掌握:

 定义字符串的2种方式

 1> 利用数组

 char name[] = "itcast";

 * 特点:字符串里面的字符是可以修改的

 * 使用场合:字符串的内容需要经常修改

 2> 利用指针

 char *name = "itcast";

 * 特点:字符串其实是一个常量字符串,里面的字符是不能修改

 * 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

4. 习题
1> 编写一个int string_len(char *s),返回字符串s的字符长度
 1 #include <stdio.h>
 2 int string_len(char *s);
 3 
 4 int main()
 5 {
 6     int size = string_len("sdtrgfgds56");
 7     
 8     printf("%d
", size);
 9     return 0;
10 }
11 
12 int string_len(char *s)
13 {
14     // 1.定义一个新的指针变量指向首字符
15     char *p = s;
16     
17     /*
18      while ( *s != '' )
19      {
20      s++;
21      }*/
22     
23     while ( *s++ ) ;
24     
25     return s - p - 1;
26 }
27 
28 /*
29  int string_len(char *s)
30  {
31  // 记录字符的个数
32  int count = 0;
33  
34  // 如果指针当前指向的字符不是''
35  // 首先*s取出指向的字符
36  // 然后s++
37  while ( *s++ )
38  {
39  // 个数+1
40  count++;
41  
42  // 让指针指向下一个字符
43  //s = s + 1;
44  //s++;
45  }
46  
47  return count;
48  }
49  */
50 
51 /*
52  int string_len(char *s)
53  {
54  // 记录字符的个数
55  int count = 0;
56  
57  // 如果指针当前指向的字符不是''
58  while ( *s != '')
59  {
60  // 个数+1
61  count++;
62  
63  // 让指针指向下一个字符
64  //s = s + 1;
65  s++;
66  }
67  
68  return count;
69  }*/

7、 返回指针的函数
● 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的
● 返回指针的函数的一般形式为:类型名 * 函数名(参数列表)
 1 #include<stdio.h>
 2 
 3 char  *test();
 4 
 5 int main()
 6 
 7 {
 8     
 9     char *name=test();
10     
11     printf("name=%s
",name);
12     
13     return 0;
14     
15 }
16 
17 
18 
19 char *test() //返回指针的函数
20 
21 {
22     
23     return "rose";
24     
25 }

 

8、 指向函数的指针
1. 为什么指针可以指向一个函数?

函数作为一段程序在内存中也要占据部分存储空间它也有一个起始地址即函数的入口地址函数有自己的地址那就好办了我们的指针变量就是用来存储地址的因此可以利用一个指针指向一个函数其中函数名就代表着函数的地址

2. 指向函数的指针的定义

定义的一般形式函数的返回值类型 (*指针变量名)(形参1, 形参2, ...);

3. 使用注意
● 由于这类指针变量存储的是一个函数的入口地址所以对它们作加减运算(比如p++)是无意义的
● 指向函数的指针变量主要有两个用途

  调用函数

  将函数作为参数在函数间传递

 指针总结

一、指针变量的定义

1. 格式:变量类型 *指针变量名;

2. 举例:int *p;   char *p2;

3. 注意:定义变量时的*仅仅是指针变量的象征

二、利用指针变量简单修改其他变量的值

1.指向某个变量

int a;

int *p;

p = &a;

或者

int *p = &a;

2.修改所指向变量的值

*p = 10;

3.在函数内部修改外面变量的值

int a = 10;

change(&a);

void change(int *n)

{

    *n = 20;

}

三、指针与数组

1.将数组当做函数参数传入时,会自动转为指针

四、指针与字符串

1.定义字符串的2种方式

1> 利用数组

char name[] = "itcast";

* 特点:字符串里面的字符是可以修改的

* 使用场合:字符串的内容需要经常修改

2> 利用指针

char *name = "itcast";

* 特点:字符串其实是一个常量字符串,里面的字符是不能修改

* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用

2.定义字符串数组

1> 利用二维字符数组

char names[2][10] = {"jack", "rose"};

2> 利用指针数组

char *names[2] = {"jack", "rose"};

作业1

 1 /*
 2 编写一个函数,判断某个字符串是否为回文。
 3 回文就是从左边开始读 和 从右边开始读 都是一样的,比如"abcba"
 4 */
 5 
 6 #include <string.h>
 7 #include <stdio.h>
 8 int isHuiwen(char *str);
 9 
10 int main()
11 {
12     printf("%d
", isHuiwen("abcdcba"));
13     return 0;
14 }
15 
16 /*
17  返回1代表是回文
18  返回0代表不是回文
19  */
20 int isHuiwen(char *str)
21 {
22     // 1.定义一个指向变量left指向字符串的首字符
23     char *left = str;
24     // 2.定义一个指向变量right指向字符串的末字符
25     char *right = str + strlen(str) - 1;
26     
27     while (left < right)
28     {
29         // 如果左边和右边的字符不一样
30         if (*left++ != *right--)
31         {
32             return 0;
33         }
34     }
35     
36     return 1;
37 }
 
作业2
 1 /*
 2 编写一个函数void strlink(char s[], char t[])
 3  将字符串t连接到字符串s的尾部
 4 */
 5 #include <stdio.h>
 6 
 7 void strlink(char s[], char t[]);
 8 
 9 int main()
10 {
11     char s1[20] = "michael ";
12     char s2[] = "jackson";
13     
14     strlink(s1, s2);
15     
16     printf("%s
", s1);
17     
18     return 0;
19 }
20 
21 void strlink(char s[], char t[])
22 {
23     int i = 0;
24     
25     // 判断s[i]是否为字符串的尾部
26     while ( s[i] != '' )
27     {
28         i++;
29     }
30     
31     int j = 0;
32     // 拷贝t的内容到s的后面
33     while ( (s[i] = t[j]) != '' )
34     {
35         i++;
36         j++;
37     }
38 }
39 
40 /*
41  更加精简的写法,仅作为参考(会有警告信息)
42 void strlink2(char s[], char t[])
43 {
44     int i = -1;
45     
46     // 判断s[i]是否为字符串的尾部
47     while (s[++i]) ;
48     
49     int j = 0;
50     // 拷贝t的内容到s的后面
51     while (s[i++] = t[j++]) ;
52 }*/

 

 

原文地址:https://www.cnblogs.com/zhangxiaomeng1991/p/4153112.html