指针进阶( 上 )

打印 上一主题 下一主题

主题 1595|帖子 1595|积分 4785

内容大纲

一.字符指针
二.指针数组
三.数组指针
四. 数组传参和指针传参

引言

指针是什么呢?指针是用来干什么的呢?指针的巨细是多少呢?指针的巨细具有什么属性呢?
解答:指针是个变量,用来存放变量地址的,指针的巨细是4/8个字节(32位平台/64位平台),指针的巨细是固定的。

一.字符指针

字符指针:char*

书写形式:
  1. char ch = 'a';
  2. char* pc = &ch;
复制代码
那么只可以这样写吗?
当然不是,我们还可以这样写
  1. const char* pa = "abcdef";
复制代码
起首,观察代码片断 char* pa = "abcdef",我们留意到等号右侧是一个字符串常量。然而,这并不意味着该表达式将整个字符串赋值给指针 pa。实际上,它将字符串的首字母 'a' 的地址赋给了 pa


其次,我们如何看const呢?

因为“abcdef”是常量字符串,其值是不可以改变的,加上const更加严谨、正确。
如何理解 const 关键字及其在常量字符串中的应用
在编程中,const关键字是一个非常重要的工具,它用于声明常量或只读变量。当一个变量被const修饰时,意味着该变量的值在初始化之后不能被改变。这种特性在处置处罚常量字符串时尤为重要,因为它确保了字符串的值在整个程序运行期间保持不变,从而增加了程序的坚固性和安全性。
const 关键字的作用和优点
const关键字的主要作用是保护被修饰的对象,防止意外的修改。在C语言中,const可以用来修饰变量、函数参数、返回值等,使得这些被修饰的对象成为只读的。这样做不仅增强了代码的可读性,还可以或许在编译期捕捉潜在的错误,比如试图修改常量的行为,从而避免了运行时的错误31
别的,const关键字还有助于提高程序的服从。编译器通常不会为平凡的const常量分配存储空间,而是将它们保存在符号表中,这使得const常量成为编译期间的常量,没有了存储与读内存的操作,因此服从也很高4
const 关键字在常量字符串中的应用
对于常量字符串,如 "abcdef",利用 const 关键字进行修饰是一种良好的编程实践。这是因为常量字符串本质上是不可变的,不应该被修改。通过在声明时加上 const,可以明确地表达这一意图,而且在编译时就可以或许捕捉到任何试图修改字符串的行为,从而避免了大概的错误。

接下来,我们来看一下这道题
  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. int main()
  4. {
  5.         char str1[] = "hello world";
  6.         char str2[] = "hello world";
  7.         const char* str3 = "hello world";
  8.         const char* str4 = "hello world";
  9.         if (str1 == str2)
  10.                 printf("str1 and str2 are same.\n");
  11.         else
  12.                 printf("str1 and str2 are not same.\n");
  13.        
  14.         if (str3 == str4)
  15.                 printf("str3 and str4 are same.\n");
  16.         else
  17.                 printf("str3 and str4 are not same.\n");
  18.         return 0;
  19. }
复制代码
输出效果:


解答:
起首,我们来看
char str1[] = "hello world";
char str2[] = "hello world";
这相当于个字符数组str1[]和str2[]进行初始化,在后续操作中我们可以分别对数组str1[]和str2[]的值进行改变,所以在创建这两个数组时,占用了两个不同的空间
str1==str2
这个表达式不是比力两个数组的内容而是比力两个数组元素的首地址
故:
str1 and str2 are not same.

其次,我们来看
const char* str3 = "hello world";
const char* str4 = "hello world";
在这两行代码中 "hello world"都是常量字符串,且内容均相同,没须要存储在两个不同的内存中


故:str3 and str4 are same.

二.指针数组

整型数组——存放整型变量的数组
字符数组——存放字符变量的数组
那么
指针数组——存放指针变量的数组
当我们想连续打印一组字符串时,我们就可以利用指针数组
  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. int main()
  4. {
  5.         const char* ch[4] = { "abc","def","hello","yes" };
  6.         int i = 0;
  7.         for (i = 0;i < 4;i++)
  8.         {
  9.                 printf("%s\n", ch[i]);
  10.         }
  11.         return 0;
  12. }
复制代码


当然也可以通过指针数组将多个一位数组组合在一起,形成雷同二级数组的东西
  1.         int a1[4] = { 1,2,3,4 };
  2.         int a2[4] = { 2,3,4,5 };
  3.         int a3[4] = { 3,4,5,6 };
  4.         int* a[3] = {a1,a2,a3};
  5.         int j = 0;
  6.         for (i = 0;i < 3;i++)
  7.         {
  8.                 for (j = 0;j < 3;j++)
  9.                 {
  10.                         printf("%d ", a[i][j]);
  11.                 }
  12.                 printf("\n");
  13.         }
复制代码
输出效果:



三.数组指针

字符指针——存放字符地址的指针——指向字符的指针 char*
整型指针——存放整形地址的指针——指向整型的指针 int*
那么,数组指针顾名思义
数组指针——存放数组地址的指针——指向数组的指针
书写形式:

  1.         int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
  2.         int (*p)[10] = &arr;
复制代码
&arr与arr

那么可以&arr可以写成arr吗?
我们通过代码来看一下二者到底有无区别
  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. int main()
  4. {
  5.         int arr[3] = { 0 };
  6.         printf("%p\n", arr);
  7.         printf("%p\n", &arr);
  8.         return 0;
  9. }
复制代码
输出效果:


这样一看没有区别,arr,&arr都表示了数组元素的首地址,但是真的如此吗?我们接着来看
  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. int main()
  4. {
  5.         int arr[3] = { 0 };
  6.         printf("%p\n", arr);
  7.         printf("%p\n", arr + 1);
  8.         printf("%p\n", &arr);
  9.         printf("%p\n", &arr+1);
  10.         return 0;
  11. }
复制代码
输出效果:


可见从arr 到arr+1相当于在地址上+4,而从&arr到&arr+1却加上了40,那么这表示,arr和&arr并不相同
数组指针的利用( 一般用于二维数组)

  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. void Print(int (*p)[4], int n, int m)
  4. {
  5.         int i = 0;
  6.         for (i = 0;i < n;i++)
  7.         {
  8.                 int j = 0;
  9.                 for (j = 0;j < m;j++)
  10.                 {
  11.                         printf("%d ", ((*p + i)[j]));
  12.                 }
  13.                 printf("\n");
  14.         }
  15. }
  16. int main()
  17. {
  18.         int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
  19.         Print(arr, 3, 4);
  20.         return 0;
  21. }
复制代码
此中int (*p)[4],就是将二维数组拆分成多个一维数组,4表示一维数组的元素个数



四. 数组传参和指针传参

对于一个数组,我们只可以或许做两件事1.确定命组巨细;2.获得指向该数组下标为0的元素的指针,其他操作,固然看上去我们是通过数组下标来进行操作的,但实际上是通过指针进行运算的
一维数组传参

主要有以下几个形式
  1. void test(int arr[]);
  2. void test(int arr[10]);
  3. void test(int *arr);
复制代码
二维数组传参

主要有以下几个形式
  1. void test(int arr[3][4]);
  2. void test(int arr[][4]);
  3. void test(int (*arr)[4]);
复制代码
一级指针传参

  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include<stdio.h>
  3. void Print(int* p, int sz)
  4. {
  5.         int i = 0;
  6.         for (i = 0;i < sz;i++)
  7.         {
  8.                 printf("%d ", *(p + i));
  9.         }
  10. }
  11. int main()
  12. {
  13.         int arr[4] = { 1,2,3,4 };
  14.         int* p = arr;
  15.         int sz = sizeof(arr) / sizeof(arr[0]);
  16.         Print(p, sz);
  17.         return 0;
  18. }
复制代码
输出效果:


二级指针传参

  1. #define  _CRT_SECURE_NO_WARNINGS 1
  2. #include <stdio.h>
  3. void test(int** p)
  4. {
  5. printf("num = %d\n", **p);
  6. }
  7. int main()
  8. {
  9. int n = 10;
  10. int*p = &n;
  11. int **pp = &p;
  12. test(pp);
  13. test(&p);
  14. return 0;
  15. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表