1.定义普通指针变量
int a = 15;
int *p = &a;
2.指针变量做函数参数
void swap(int*p1,int*p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
3指针的强制转换
#include<stdio.h>
int main()
{
int a=3158321;
int b=5459795;
char *p1=(char*)&a;
char *p2=(char*)&b;
printf("%s\n",p1); // 110
printf("%s\n",p2); // sos
return 0;
}
3158321在内存中1100000011000100110001
转换为char类型电脑一个字节一个字节的读
00110000 00110001 00110001
‘0’ ‘1’ ‘1’ ASCLL码
并不是把a和b转化了,只是把里面的数据暂时当做char*来看待
4指针与整数的加减运算
#include<stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
float b[5] = { 1.1,1.2,1.3,1.4,1.5 };
char c[5] = { 'v','s','x','d','m' };
int* p1 = a;
int* a1 = &a[2];
int* a2 = &a[4];
float* p2 = b;
float* b1 = &b[2];
float* b2 = &b[4];
char* p3 = c;
char* c1 = &c[2];
char* c2 = &c[4];
printf("%p\n", p1); //009AFB94
printf("%p\n", p1+1); //009AFB98
printf("%d\n", a2-a1); //结果为2
printf("\n%p\n", p2); //009AFB78
printf("%p\n", p2+1); //009AFB7C
printf("%d\n", b2 - b1); //结果为2
printf("\n%p\n", p3); //009AFB68
printf("%p\n", p3+1); //009AFB69
printf("%d\n", c2 - c1); //结果为2
return 0;
}
5多维数组
int a[5][6];
printf("%x\n",a);//指向一维数组a[0],即0行起始地址printf("%x\n",a+1);//第一行的起始地址 还可以表示为&a[1]
printf("%x\n",a[0]);//表示a[0][0]的地址 还可以表示为*a和*(a+0)
printf("%x\n",a[0]+1);//表示为第0行第1列的起始地址,还可以表示为*(a+0)+1
printf("%d\n", *(*(a+1)+1) ); //表示a[1][1]的值
6 数组指针和指针数组
(1)数组指针 是指针 指向数组的指针 形如int(*p)[4]
int a[4]={1,3,5,7};
int(*p)[4];
p=&a; //数组名取地址表示整个数组
printf("%d\n",(*p)[3]); //结果为7
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int(*p)[4];
p=a;
printf("%d\n", *(*(p+1)+1));//输出a[1][1]的值
(2)指针数组 是数组 数组里面全是指针 形如int*p[4]
char*name[]={"lyu","lji","yjie","yuji"};//指针数组定义
char*p1;
p1=name[0];//指针数组的使用name[0]里的数据是一个指针
char**p2;
p2=name;
7函数指针
(1)定义和使用指向函数的指针变量
int a,b,c;
int(*p)(int ,int );
int max(int ,int );
p=max;
c=(*p)(a,b);
(2)用指向函数的指针做函数参数
int a,b,c;
int fun(int x ,int y,int (*p)(int a,int b) );
int max(int ,int );
int min(int ,int );
int add(int ,int );
c=fun(a,b,max);
8万能指针
int a = 520;
float b]= 3.14;
char c = 'm';void*p1;//万能指针
p1=&a;
printf("%d", *(int *)p1);
void*p2;
p2=&b;
printf("%f", *(float *)p1);
void*p3;
p3=&c;
printf("%c", *(char *)p1);
9动态内存分配
在堆区(很大)开辟空间可以永久存在
#include<stdio.h>
#include<stdlib.h>
int main()
{
int*p;
p=(int*)malloc(sizeof(int));//开辟4个字节空间
free(p);//释放空间
p=(int*)calloc(50,4);//开辟50个4字节空间
realloc(p,16);//将p指向的已分配的动态空间改为16字节
return 0;
}
10柔性数组
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Girl
{
char name[16];
int age;
int love_len;
const char* love[];
};
Girl* girl_new(int n)
{
Girl* girl = (Girl*)malloc(sizeof(Girl)+n*sizeof(char*));
girl->love_len = n;
return girl;
}
void girl_init(Girl* girl, const char* name, int age, const char* loves[])
{
strcpy(girl->name, name);
girl->age = age;
for (int i = 0; i < girl->love_len; i++)
{
girl->love[i] = loves[i];
}
}
int main()
{
const char* loves[] = {"游戏","学习","看书","电影","唱歌"};
Girl* pyujie = girl_new(5);
girl_init(pyujie,"玉杰",20,loves);
return 0;
}
//头文件
#include<time.h>
//获得当前时间
int t=time(NULL);
//设置随机数种子
srand(t);
//获得随机数
int a=rand();
//产生随机数范围:[m,n]
int a=m+rand()%(n-m+1);
return和exit的区别
return结束当前所在函数
exit是一个库函数,结束整个程序
例如
exit(0):正常运行程序并退出程序;
exit(1):非正常运行导致退出程序;
如果在别的c文件下写了一些函数需要再主函数文件里面声明,
可以新建一个头文件把声明写在里面,
然后再主函数里用include引用这个头文件。
头文件只能声明千万别定义。
防止调用头文件时重复声明的方法
①#ifndef 头文件名 //如果没定这个宏
#define 头文件名
声明部分
#endif
②在头文件里加一个
#pragma once(在vs里最可以用)