C语言基础知识之五
来源:互联网 发布:土工cbr试验量算法 编辑:程序博客网 时间:2024/05/22 07:00
函数指针
int *a; //定义变量,a是整型指针变量
int a(); //定义函数,a是函数,返回值为int
int * a(); /定义函数,a是函数,返回值为int*
int *a[10]; //定义变量,a是数组,存放10单元整型指针的数组
int (*a)[10]; //定义变量,a是指针,指向10个数组单元的指针
int (*a)(); //定义函数,a是指针,指向函数的指针,返回值为int
1.函数代码存储空间的起始地址(又称入口地址)称为这个函数的指针。
如:
int (* p)( int ,int );
这是定义一个指向函数的指针变量,指针变量p的返回值类型是整型,并且这个函数有两个整型参数。
2.用函数指针变量调用函数
举例:
int Max(int a,int b){return a>b?a:b;}int main(){int a=5;int b=3; //int c=Max(a,b); //(1)通过函数名调用Max函数 //printf("%d\n",c);int (*p)(int ,int ); //定义指向函数的指针变量p, //只需要说明p的返回值是整型且有两个整型参数就行,即只指明int,用int x也可以p=Max; //使p指向Max函数首地址, p=&Max也可以 //int c=(*p)(a,b); //(2)通过指针变量调用Max函数printf("%d\n",p(a,b)); //printf("%d\n",(*p)(a,b));也可以return 0;}
3.定义和使用指向函数的指针变量
形式:类型名 (*指针变量名)(函数参数表列);
如:
int (*p)(int ,int );
说明:
(1)定义指向函数的指针变量,只能指向在定义时指定的那个类型的函数,如int (*p)(int ,int);是属于一个整型返回值,两个整型变量的参数的类型。即函数指针指向一个函数族
(2)如果指针调用函数,必须使指针指向该函数,如 p=Max;
(3)在给函数指针变量赋值时,只给出函数名不必给出参数
如:p=Max; //将函数入口地址赋给p
(4)函数指针调用函数时,只需用(*p)代替函数名即可
(5)指向函数的指针变量不能进行算术运算
(6)函数名调用函数,只能调用指定的某一个函数;而指针变量调用函数,可以根据不同的情况先后调用不同的函数。
结构体
C语言允许用户自己建立有不同类型数据组成的组合型的数据结构,它称为结构体。
1.结构体类型形式:
struct 结构体名
{
类型名 成员名;
};
2.结构体中可以使用的类型:
(1)基本数据类型 (2)前面已经定义好的结构体 (3)结构体本身的指针
//以下是举例,不是具有功能的完整代码#include<stdio.h>#include<string.h>struct Student //struct Student是类型名,student是结构体名{char name[20];int age;};struct A{ int a; //char a;//error,不能同名 char b;};struct B{ int c; //(1) struct A sa; //(2) //struct B sb; //error,因为不知道sb的内存大小 struct B *pb; //OK,因为指针为4个字节,已知 (3)};struct C{ struct A c; int a;//此处的结构体名称a与结构体A中的a不在一个级别,不冲突};int main(){struct Student stu1={"liubei",30};struct Student stu2;stu2=stu1; //同类的结构体变量可以互相赋值//stu2.name="caocao";//error 不能直接将字符串常量赋给字符数组strcpy(stu2.name,"caocao");//ok,用字符串拷贝函数printf("%s,%d\n%s\n",stu1.name,stu1.age,stu2.name);struct C sc; sc.c.a=10; sc.a=100;//a不冲突,因为等级不同 printf("%d.%d\n",sc.c.a,sc.a); return 0;}
3.定义结构体类型变量
(1)先声明结构体类型,再定义该类型的变量
如:
struct Student{char name [20];int age;};int main(){struct Student stu1;struct Student *p;return 0;}
(2)在声明类型的同时定义变量
struct Student {char name[20];int age;};stu1;
4.访问成员的方式:(1)结构体普通变量通过 · 访问成员;(2)结构体指针变量通过->访问成员
struct A{ int a; int *p;};struct B{ struct A c; struct A *d; int e; int *f;};struct Student { char name[20]; int age;};int main(){ struct B bb; struct B *pb; bb.c.a; //访问成员 bb.c.p; bb.d->a; bb.d->p; bb.e; bb.f; pb->c.a;//或(*pb).c.a (*pb)是对pb进行解引用,不过用起来麻烦,使用较少 pb->c.p; pb->d->a; pb->d->p; pb->e; pb->f; struct Student stu1={"liubei"};//聚合类型(数组和结构体)只初始化一部分时,其余部分默认为0,此处即age=0 stu1.age=33;//修改stu1的年龄为33 struct Student *ps=&stu1; (*ps).age=28;//或ps->age=28;比较常用 //指向符->和[]自带解引用}
区分函数调用与函数声明的方法:函数声明有数据类型,函数调用没有数据类型
在C语言中,调用不带参数的函数,如 Student stu1();
在C++中,调用不带参数的函数,如 Student stu1; //c++没有参数的时候不用带括号
在C语言中,结构体关键字struct在调用时不可以省略;
在C++中,结构体关键字struct在调用时可以省略;
struct A{ int a; A() { printf("haha "); } A(int x) { a=x; printf("A(int x)\n"); }};int main(){ A aa; //c++没有参数的时候不用带括号 A bb(3);return 0;}
打印结果: haha A(int x)
用typedef声明新类型名
typedef是关键字,作用是类型重定义,即给类型取个别名
如:typedef unsigned longlong uint64;即给unsigned long long类型取个别名叫uint64
1.用一个别名代替复杂的类型名
(1)用别名代替结构体类型
typedef struct Student Student; //Student是别名
即:
typedef struct Student{char name[20];int age;}Student; //Student为新的类型名(别名),代替typedef struct Student{code}
用typedef声明后再去定义变量时不需要再写类型名struct Student,如直接定义为Student sa;
(2)用别名代替数组类型
typedef int Num[20]; //声明Num为整型数组类型名
Num a; //定义整型数组a
(3)用别名代替指针类型
typedef int * p; //声明p为整型指针类型
p a[10]; //a是指针数组
(4)用别名代替指向函数的指针类型
typedef int (* pfun)(int ,int); //pfun是函数指针类型,该函数返回整型值
pfun p; //p为函数指针类型
归纳 声明新类型名的方法:
按定义变量的方式,把变量名换上新类型名,并且在最前面加上typedef,就声明了新类型名代替原来的类型。
typedef 与#define
typedef int * Pint;//重定义类型# define PINT int *//字符替换int main(){ Pint d,e; //d为指针,e为指针 PINT f,h;//int *f,h,故f为指针,h为int型}
typedef 是类型重定义,在编译阶段有效,有类检查功能,有自己的作用域 # define
作用是字符替换,是预编译命令,没有检查功能,没有作用域的限制
- C语言基础知识之五
- c语言之c语言基础知识
- C语言基础知识之四
- C语言基础知识之三
- C语言基础知识之二
- C语言基础知识之函数
- iOS C语言之基础知识
- C语言基础知识之(五):break 和 continue 运用详解
- Objective-C基础知识之(五):NSString
- iOS开发之--C语言之基础知识
- 简明C语言教程(五)预备计算机专业基础知识
- C语言复习之结构体基础知识
- C语言复习之结构体基础知识
- C语言复习之结构体基础知识
- C语言复习之结构体基础知识
- ios之C语言基础知识串联
- C语言基础知识之#pragma once
- c语言基础知识之排序方法
- 如何使用MindManager模板创建思维导图
- 打成aar/Jar(项目模块化) -Android Studio
- MindManager基础教程
- 使用lineRender画线时不能在UI图上显示线的问题解析
- java中的内存模型
- C语言基础知识之五
- 安卓模拟器如何连接adb
- 猜数字的小游戏
- DateFormat 总结
- MySQL学习
- 动态代理和cglib实现
- 170506 解密-ssctf签到wp 汇编-数据标号
- LeetCode:Excel Sheet Column Title
- C++链表:极简版的单向链表类