C语言基础知识----指针数组 && 数组指针 && 函数指针 &&指针函数

指针数组 && 数组指针

char (*ptr)[5];    //定义一个指向数组指针ptr,指向包含5个char类型的数组

char *a[5];      //定义一个指针数组a,包含5个char*类型指针
#include <stdio.h>
int main(void)
{
    char *a[5]={"red","white","blue","dark","green"};
    printf("%s    %c    %s\n", a[0], *(a[0]+1), a[1]+1);
    printf("%x    %x\n",a[0], a[1]);
    char m[2][5]={"xxx", "yyyy"};
    char (*ptr)[5]=m;
    printf("%x    %s    %s    %x    %s\n", ptr[0], ptr, ptr[1], ptr[0]+2, ptr[0]+1);
    printf("%d    ",sizeof(a));
    printf("%d    ",sizeof(m));
    return 0;

}

@1  定义指针数组,组中元素均为char *类型

@2 定义数组指针,ptr类型为char (*)[],m类型为char [][],这两类型间是可以赋值的。但他们不是完全等价的。

@3 a的类型为char *[5],sizeof(a)=sizeof(char *)*5;    m的类型为char [][]的二维数组,sizeof(m)求得它在内存中实际所占字节,有些编译器出于效率考虑会对字节进行对齐。

运行结果如下

函数指针 && 指针函数

  函数指针和其它指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数。

  下面是一种初始化函数指针的方法:

  int fun( int );

int ( * pf ) ( int ) = &fun;

创建函数指针pf并将其指向函数fun。在函数指针的初始化之前具有fun的原型是很重要的,否则编译器无法检查fun的类型与pf所指向的类型一致。

初始化声明后,我们可以有以下三种方式调用函数:

int  ans;

1)     ans = fun( 25 );

2)     ans = ( *pf ) ( 25 );

3)     ans = pf ( 25 );

语句1简单的使用名字调用函数fun。但它的执行过程可能跟你想的不一样:函数名fun首先被转换为一个函数指针,该指针指向内存中的一块位置。然后,函数调用操作符调用函数,执行开始于这个地址的代码。

语句2对pf执行间接访问操作,将pf转换为函数名。但这种转换其实是不必要的,编译器在执行函数调用操作符之前又会把它转换回去。

语句3和前两条执行效果一样的。

函数指针的常见用途就是把函数指针作为参数传递给函数,下面是例子。

#include <stdio.h>
#include <string.h>
int compare_int(void const *a, void const *b)
{
	if( *(int *)a == *(int *)b)
		return 0;
	else
		return 1;
}
int compare_char(void const *a, void const *b)
{
	if(strcmp ((char *)a, (char *)b) == 0)
		return 0;
	else
		return 1;
}
void Compare(void const *a, void const *b,int (*compare)(void const *, void const *))
{
	if(compare(a, b) == 0)
		printf("they are equal\n");
	else
		printf("not equal\n");
}
int main(void)
{
	int m=4,n=5;
	Compare(&m, &n, compare_int);
	char a[4]="abc",b[4]="abc";
	Compare(a, b, compare_char);
} 

运行结果:

使用以上技巧的函数被称为回调函数(callback function)。用户将一个函数指针作为参数传递给其它函数,后者将“回调”用户的函数。分别为比较整型与字符串编写不同的比较函数compar_int(void
const *,void const *)和compar_char(void const *,void const *),通过向Compare(const void *,const void *,int (*compare)(void const *, void const *))传递不同的函数指针,通过同一接口实现对不同类型数据的比较。

指针函数,指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果没有返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

C语言基础知识----指针数组 && 数组指针 && 函数指针 &&指针函数

时间: 2024-12-20 19:06:04

C语言基础知识----指针数组 && 数组指针 && 函数指针 &&指针函数的相关文章

C语言基础学习3:数组与指针

数组元素的指针就是数组元素的地址. 1.指向数组元素的指针 C语言规定数组名(不包括形参数组名,形参数组并不占据实际的内存单元)代表数组中的首元素(即序列为0的元素)的地址. int a[10]; int *p1,*p2; p1 = &a[0]; p2 = a; p1和p2指向同一个数组a[10]. 2.通过指针引用数组元素 按C语言的规定,如果指针变量p已指向数组中的一个元素,则p+1指向同一个数组中的下一个元素,而不是将p的值(地址)简单的加1. 如果p的初值为&a[0],则 (1)

js 基础知识 对象与数组

对象是一种无序属性的集合,每个属性都有自己的名字和值. 对象的创建有很多种,我在第一章已经说过了. 如何遍历一个对象: var x;var txt="";var person={fname:"Bill",lname:"Gates",age:56}; for (x in person)       //x其实是一个变量,代表的是person对象的属性{txt=txt + person[x];              //person[属性]  等

C语言基础知识----易让人头疼的关键字----const &amp;&amp; typedef &amp;&amp; define

const关键字 const=read only,修饰的为只读变量而不是常量.const修饰的变量不能用作数组的维数也不能放在switch语句的case:之后. 主要作用有: 1.通过把不希望被修改的变量或参数用const来修饰,编译器会保护这些变量不被修改增强系统的可靠性: 2.增强代码的可读性 [html] view plaincopyprint? const int a;      //a为常量不能被修改 int const a;      //a为常量不能被修改 const int *a

OC语言基础知识

OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能的类. 术语:OO面向对象.OOP面向对象编程 二.类 (一)关于类 类的设计只关注三个东西:类名.属性和方法 注意:一般名词都是类,拥有相同属性和行为的对象都可以抽象为一个类,类名是标识符的一种,需要符合规范,通常类名的第一个字母大写,且不能有下划线,如果有多个单词则使用驼峰标识.在对方法进行类的

李洪强iOS开发之OC语言基础知识

OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能的类. 术语:OO面向对象.OOP面向对象编程   二.类 (一)关于类 类的设计只关注三个东西:类名.属性和方法 注意:一般名词都是类,拥有相同属性和行为的对象都可以抽象为一个类,类名是标识符的一种,需要符合规范,通常类名的第一个字母大写,且不能有下划线,如果有多个单词则使用驼峰标识.在对方法进行

C语言基础知识整理

用一个简单的c程序例子,介绍C语言基础知识的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #includemain(){int a,b,sum;  a=20;       b=15;       sum=a+b;   printf("a=%d,b=%d,sum=%d\n",a,b,sum); } 重点说明: 1.任何一个c语言程序都必须包括以下格式: main(){   } 这是c语言基本知识结构,任何一个程序都必须包含这个结构.

C#语言基础知识(6):C# List&lt;T&gt;用法

List<T>和List的用法是一模一样的,不同的是,List支持任何类型而List<T>只支持T类型,T是在定义时指定的类型. 如: List<string> list=new List<string>; 这样的话,每个list里的元素都是字符串. 同理, List<int> list=new List<int>; 这样的话,每个list里的元素都是整形. List<T>是一个实现List接口反省集合,分开说的话List

C#语言基础知识(2):C#中多态

我的理解是:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态. 1: OverRide 实现多态 1 public class Animal 2 { 3 public virtual void Eat() 4 { 5 Console.WriteLine("Animal eat"); 6 } 7 } 8 public class Dog : Animal 9 { 10 public override void Eat() 11 { 12 Console.WriteLin

C#语言基础知识(1):C#中关于重载和重写

Overload:重载就是在同一个类中,方法名相同,参数列表不同.参数列表不同包括:参数的个数不同,参数类型不同. 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace OverLoading 6 { 7 class Program 8 { 9 public static int max(int i, int j) //静态方法 10 { 11 if (i > j) 12 re