(二)数组、指针、函数
来源:互联网 发布:非农数据对美元影响 编辑:程序博客网 时间:2024/06/06 08:38
一、数组
1、一维数组
1》定义
2》初始化
3》使用
4》存储
2、多维数组
1》定义
2》初始化
3》使用
4》存储
3、变长数组
4、数组传参
地址传递:传数组名和元素个数
#include <stdio.h>//void fun(int n,int b[])void fun(int n,int *b){int i;for(i = 0; i < n; i++)printf("%d\t",b[i]);printf("\n");}int main(void){int a[5] = {1,2,3,4,5};fun(5,a);return 0;}
#include <stdio.h>//void fun(int n,int m, b[][m])void fun(int n,int m, int (*b)[m]){int i,j;for(i = 0; i < n; i++){for(j = 0; j < m; j++)printf("%d\t",b[i][j]);printf("\n");}}int main(void){int a[2][3] = {{1,2,3},{4,5,6}};fun(2,3,a);return 0;}
二、指针
1、概念:
在C语言中,内存单元的地址称为指针,专门用来存放地址的变量,称为指针变量(pointervariable), 在不影响理解的情况中,有时对地址、指针和指针变量不区分,通称指针。
2、指针三要素:
当给一个指针初始化或者赋值之后,则该指针存在三要素,例如:
int a = 100;
int *pa = &a;
此时,对于pa来说,有以下三个表达式:
*p 表示p指向的数据
p 表示p的内容
&p 表示变量p在内存中的地址
3、指针的运算:
1》赋值: =
2》取值:*
3》取地址:&
4》加法运算:+
只能加一个整数
5》减法运算:-
可以减一个整数
也可以两个同类型的指针相减
6》关系运算:> < >= <= == !=
表示地址高低的比较
4、const关键字
5、多级指针
在C语言中,把存储指针变量地址的变量,称为多级指针变量,简称多级指针。
int a = 100;
int *p1 = &a; //p1为一级指针
int**p2 = &p1; //p2为二级指针
int ***p3 = &p2; //p3为三级指针
综上:n级指针变量中可以存放n-1级指针变量的地址。
#include <stdio.h>int main(void){int a = 100;int *p1 = &a; //p1为一级指针int **p2 = &p1;//p2为二级指针int ***p3 = &p2;//p3为三级指针printf("a = %d\n",a);printf("*p1 = %d\n",*p1);printf("**p2 = %d\n",**p2);printf("***p3 = %d\n",***p3);return 0;}
6、void关键字
1》修饰函数返回值
表示该函数没有返回值
2》修饰函数的参数
表示该函数没有参数
3》定义指针
表示该指针中可以存放任何类型的地址,通常我把它称为通用指针。
#include <stdio.h>int main(void){void *p;int a = 100;p = &a;printf("a : %d\n",a);printf("*p : %d\n",*(int*)p);char b = 'A';p = &b;printf("b : %c\n",b);printf("*p : %c\n",*(char*)p);float c = 3.4;p = &c;printf("c : %f\n",c);printf("*p : %f\n",*(float*)p);return 0;}
三、指针和数组的关系:
1、指针可以指向一个数组,数组指针
2、数组中可以存储多个相同类型的地址,指针数组
#include <stdio.h>int main(void){#if 1int a[5] = {1,2,3,4,5};int *b[5] = {a,a+1,a+2,a+3,a+4};int *p = a;int * *pb = b;int i;for(i = 0; i < 5; i++)printf("%d\t%d\n",p[i],*(p+i));for(i = 0; i < 5; i++)printf("%d\t",*pb[i]);printf("\n");#elseint a[2][3] = {{1,2,3},{4,5,6}};int(*p)[3] = a;int i,j;for(i = 0; i < 2; i++)for(j = 0; j < 3; j++)printf("%d\t%d\t%d\n",p[i][j],*(p[i]+j),*(*(p+i)+j));#endifreturn 0;}
3、带参的主函数
#include <stdio.h>/** argc : 命令行参数个数argv : 命令行参数 *///int main(int argc, char *argv[])int main(int argc, char **argv){int i;printf("argc = %d\n",argc);for(i = 0; i < argc; i++)printf("%s\n",argv[i]);return 0;}
四、函数
1、基本概念
1》函数的定义
2》函数的声明
3》函数的调用
4》实参,形参及它们的关系
2、函数传参
1》传参方式:
1)值传递:
在被调用函数中不能改变实参
实参类型和形参类型相同
2)地址传递
在被调用函数中可以改变实参
形参类型是实参类型对应的指针类型
2》根据实参的类型可以将传参分为以下几种
1)实参是常量
值传递
2)实参是基本类型变量
值传递
地址传递
3)实参是数组
地址传递:传数组名和元素个数
4)实参是指针变量
值传递:#include <stdio.h>void fun1(int *p1,int *p2){int *t,b;//不能改变实参的值t = p1;p1 = p2;p2 = t;//可以改变实参指向的数据b = *p1;*p1 = *p2;*p2 = b;}void fun2(int **p1,int **p2){#if 0int *t;//可以改变实参的值t = *p1;*p1 = *p2;*p2 = t;#else//实参指向的数据也可义改变int b;b = **p1;**p1 = **p2;**p2 = b;#endif}int main(int argc, char **argv){int a = 3,b = 5;int *pa = &a, *pb = &b;#if 0printf("pa = %p,pb = %p\n",pa,pb);printf("a = %d\t,b = %d\n",a,b);fun1(pa,pb); //值传递,在被调用函数中不能改变pa和pbprintf("pa = %p,pb = %p\n",pa,pb);printf("a = %d\t,b = %d\n",a,b);#endif#if 1printf("pa = %p,pb = %p\n",pa,pb);printf("a = %d\t,b = %d\n",a,b);fun2(&pa,&pb);//地址传递,在被调用函数中可以改变pa和pbprintf("pa = %p,pb = %p\n",pa,pb);printf("a = %d\t,b = %d\n",a,b);#endifreturn 0;}
3) 返回函数的地址
4)返回值字符型指针#include <stdio.h>int fun1(void){int x = 123;return x;}char * fun2(void){return "hello world";}int *fun3(int n,int a[]){int i;for(i = 0; i < n; i++)a[i] *= 2;return a;}void fun(void){printf("hello world\n");}typedef void(*TYPE)(void);//void(*fun4(void))(void)TYPE fun4(void){return fun;}char *fun5(void){//char p[] = "hello world"; //p不能返回char *p = "hello world";//p可以返回return p;}int main(int argc, char **argv){#if 1char *str;str = fun5();printf("%s\n",str);#elsevoid (*p)(void);p = fun4();p();int arr[5] = {1,2,3,4,5};int *p,i;for(i = 0; i < 5; i++)printf("%d\t",arr[i]);printf("\n");p = fun3(5,arr);for(i = 0; i < 5; i++)printf("%d\t",arr[i]);printf("\n");#endifreturn 0;}
通用行Makefile,在当前目录下需要生成多个可执行文件是直接make,同时根据时间戳分别一一生成对应文件名的可执行文件
CC = gccCFLAGS = -Wall -g -O0#wildcard 执行make时,将当前目录下所有*.c的文件名赋给SRCSRC = ${wildcard *.c}#patsubst 根据第一个参数,在第三个参数中匹配对应的文件名,匹配成功则将其转换成第二个参数的格式OBJS = ${patsubst %.c,%,$(SRC)}#all为伪目标all:$(OBJS)%:%.c$(CC) -o $@ $^ clean:$(RM) $(OBJS)
- (二)数组、指针、函数
- C程序设计语言--指针与数组(二) 指针数组 数组指针 函数指针 指针函数
- 关于函数(二)数组指针和指针数组
- 数组指针与指针数组(二)
- C语言中的指针(指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针)
- 指针学习(二)指针与数组
- 指针与数组(二)
- 数组与指针(二)
- 数组和指针(二)
- 指针复习(二)字符串、数组、函数与指针
- 函数指针指针数组
- 数组指针、函数指针
- 指针&数组&函数指针
- 函数指针数组指针!
- 指针,指针数组,数组指针,函数指针
- 指针(数组、常量、函数)
- C++指针探讨 (二)函数指针
- C/C++编程(二)--指针数组与数组指针
- ES6系列之---数组新增的内置函数
- Android 控制线程的开始关闭
- 工作问题(SQL)
- 常用开发资源整理(持续更新)
- mysql安装在centos7报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
- (二)数组、指针、函数
- 关于HTML文本 (上)
- ubuntu下visual studio code配置C++环境
- 大学小结
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
- 贾跃亭案例
- 新起点
- network namespace 介绍和ip netns 命令的使用
- AdvancedInstaller打包工具使用(五)