做网站的钱叫什么科目,企业做网站的好处有哪些,wordpress页面构造器,蓝色系网站C指针 文章中我们介绍了指针的基本概念和应用简介。我们有提到指针可以使用在链表、队列和二叉树#xff0c;等等。但是这些都会比较复查#xff0c;后面数据结构” 时#xff0c;我们会用专门的章节来讲解这些知识。这篇文章#xff0c;详细的探讨一下指针和其他关联… C指针 文章中我们介绍了指针的基本概念和应用简介。我们有提到指针可以使用在链表、队列和二叉树等等。但是这些都会比较复查后面数据结构” 时我们会用专门的章节来讲解这些知识。这篇文章详细的探讨一下指针和其他关联的具体应用。1. 指针和数组的关系 在C语言中指针与数组之间的关系十分密切。实际上许多可以用数组完成的工作都可以使用指针来完成。一般来说用指针编写的程序比用数组编写的程序执行速度快但另一方面用指针实现的程序理解起来稍微困难一些。我们先声明一个数组int a[10];// 声明一个int类型的数组这个数组有10个元素
我们可以用 a[0]、a[1]、...、a[9] 来表示这个数组中的10个元素这10个元素是存储在一段连续相邻的内存区域中的。接下来我们再声明一个指针int *p; // 声明一个int类型的指针变量
p 是一个指针变量指向内存中的一个区域。如果我们对指针 p 做如下的初始化p a[0]; // 对指针进行初始化p将指向数组 a 的第 1 个元素 a[0]
我们知道对指针进行自增操作会让指针指向与当前元素相邻的下一个元素即 *(p 1) 将指向 a[1] 同样的 *(p i) 将指向 a[i] 。因此我们可以使用该指针来遍历数组 a[10] 的所有元素。可以看到数组下标与指针运算之间的关系是一一对应的。而根据定义数组类型的变量或表达式的值是该数组第 1 个元素的地址且数组名所代表的的就是该数组第 1 个元素的地址故上述赋值语句可以直接写成p a; // a 为数组名代表该数组最开始的一个元素的地址
很显然一个通过数组和下标实现的表达式可以等价地通过指针及其偏移量来实现这就是数组和指针的互通之处。但有一点要明确的是数组和指针并不是完全等价指针是一个变量而数组名不是变量它数组中第 1 个元素的地址数组可以看做是一个用于保存变量的容器。更直接的方法我们可以直接看二者的地址并不一样#include stdio.h int main(){int x[10] {1,2,3,4,5,6,7,8,9,0};int *p x;printf(x的地址为%p\n,x);printf(x[0]的地址为%p\n,x[0]);printf(p的地址为%p\n,p); // 打印指针 p 的地址并不是指针所指向的地方的地址p 2;printf(*(p2)的值为%d\n,*p); // 输出结果为 3*(p2)指向了 x[2]return 0;
}
结果如下可以看到 x 的值与 x[0] 的地址是一样的也就是说数组名即为数组中第 1 个元素的地址。实际上打印 x 后发现x 的地址也是这个值。而 x 的地址与指针变量 p 的地址是不一样的。故而数组和指针并不能完全等价。2. 指针数组指针是一个变量而数组是用于存储变量的容器因此指针也可以像其他变量一样存储在数组中也就是指针数组。指针数组是一个数组数组中的每一个元素都是指针。声明一个指针数组的方法如下// 声明一个指针数组该数组有10个元素其中每个元素都是一个指向int类型的指针
int *p[10];
在上述声明中由于 [] 的优先级比 * 高故 p 先与 [] 结合成为一个数组 p[]再由 int * 指明这是一个 int 类型的指针数组数组中的元素都是 int 类型的指针。数组的第 i 个元素是 *p[i]而 p[i] 是一个指针。由于指针数组中存放着多个指针操作灵活在一些需要操作大量数据的程序中使用可以使程序更灵活快速。3. 数组指针数组指针是一个指针它指向一个数组。声明一个数组指针的方法如下int (*p)[10]; // 声明一个数组指针 p 该指针指向一个数组
由于 () 的优先级最高所以 p 是一个指针指向一个 int 类型的一维数组这个一维数组的长度是 10这也是指针 p 的步长。也就是说执行 p1 时p 要跨过 n 个 int 型数据的长度。数组指针与二维数组联系密切可以用数组指针来指向一个二维数组如下#include stdio.hint main(){int arr[2][3] {1,2,3,4,5,6}; // 定义一个二维数组并初始化int (*p)[3]; // 定义一个数组指针指针指向一个含有3个元素的一维数组 p arr; // 将二维数组的首地址赋给 p此时 p 指向 arr[0] 或 arr[0][0]printf(%d\n,(*p)[0]); // 输出结果为 1p; // 对 p 进行算术运算此时 p 将指向二维数组的下一行的首地址即 arr[1][0]printf(%d\n,(*p)[1]); // 输出结果为5return 0; }
4. 结构体和指针1 简单介绍一下结构体结构是一个或多个变量的集合这些变量可能为不同的类型为了处理的方便而将这些变量组织在一个名字之下。由于结构将一组相关的变量看做一个单元而不是各自独立的实体因此结构有助于组织复杂的数据特别是在大型的程序中。声明一个结构的方式如下struct message{ // 声明一个结构 messagechar name[10]; // 成员int age;int score;
};typedef struct message s_message; // 类型定义符 typedef
s_message mess {tongye,23,83}; // 声明一个 struct message 类型的变量 mess,并对其进行初始化 /* 另一种更简便的声明方法 */
typedef struct{char name[10];int age;int score;
}message;
可以使用 “结构名.成员” 的方式来访问结构中的成员如下2 结构体指针 结构指针是指向结构的指针以上面的结构为例可以这样定义一个结构指针s_message *p; // 声明一个结构指针 p 该指针指向一个 s_message 类型的结构
*p mess; // 对结构指针的初始化与普通指针一样也是使用取地址符
C语言中使用 “-” 操作符来访问结构指针的成员举个例子#include stdio.htypedef struct{char name[10];int age;int score;
}message;
int main(){message mess {tongye,23,83};message *p mess;printf(%s\n,p-name); // 输出结果为tongyeprintf(%d\n,p-score); // 输出结果为83return 0;
}
5. 指针和函数的关系C语言的所有参数均是以“传值调用”的方式进行传递的这意味着函数将获得参数值的一份拷贝。这样函数可以放心修改这个拷贝值而不必担心会修改调用程序实际传递给它的参数。 1 指针作为函数的参数传值调用的好处是是被调函数不会改变调用函数传过来的值可以放心修改。但是有时候需要被调函数回传一个值给调用函数这样的话传值调用就无法做到。为了解决这个问题可以使用传指针调用。指针参数使得被调函数能够访问和修改主调函数中对象的值。用一个例子来说明#include stdio.h
// 参数为普通的 int 变量
void swap1(int a,int b)
{int temp;temp a;a b;b temp;
}
// 参数为指针接受调用函数传递过来的变量地址作为参数对所指地址处的内容进行操作
// 最终结果是地址本身并没有改变但是这一地址所对应的内存段中的内容发生了变化即x,y的值发生了变化
void swap2(int *a,int *b)
{int temp; temp *a;*a *b;*b temp;
}
int main()
{int x 1,y 2;swap1(x,y); // 将 x,y 的值本身作为参数传递给了被调函数printf(%d %5d\n,x,y); // 输出结果为1 2swap(x,y); // 将 x,y 的地址作为参数传递给了被调函数printf(%d %5d\n,x,y); // 输出结果为2 1return 0;
}
2 指向函数的指针在C语言中函数本身不是变量但是可以定义指向函数的指针也称作函数指针函数指针指向函数的入口地址。这种类型的指针可以被赋值、存放在数组中、传递给函数以及作为函数的返回值等等。声明一个函数指针的方法如下返回值类型 * 指针变量名[形参列表];int (*pointer)(int *,int *); // 声明一个函数指针
上述代码声明了一个函数指针 pointer 该指针指向一个函数函数具有两个 int * 类型的参数且返回值类型为 int。下面的代码演示了函数指针的用法#include stdio.h
#include string.h// 声明一个函数 str_comp该函数有两个 const char 类型的指针函数的返回值为 int 类型
int str_comp(const char *m,const char *n); // 声明一个函数 comp ,注意该函数的第三个参数是一个函数指针
void comp(char *a,char *b,int (*prr)(const char *,const char*)); int main()
{char str1[20]; // 声明一个字符数组char str2[20];
// 声明并初始化一个函数指针且返回值为 int 类型int (*p)(const char *,const char *) str_comp; gets(str1); // 使用 gets() 函数从 I/O 读取一行字符串 gets(str2);comp(str1,str2,p); // 函数指针 p 作为参数传给 comp 函数return 0;
}int str_comp(const char *m,const char *n)
{// 库函数 strcmp 用于比较两个字符串if(strcmp(m,n) 0) return 0;elsereturn 1;
}/* 函数 comp 接受一个函数指针作为它的第三个参数 */
void comp(char *a,char *b,int (*prr)(const char *,const char*))
{if((*prr)(a,b) 0)printf(str1 str2\n);elseprintf(str1 ! str2\n);
}
推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈嵌入式Linux微信扫描二维码关注我的公众号