c[day7]

指针

  • int* p,q;与int *p,q;相等,“ * ”是一对一的,空格位置不影响。
  • void f(int *p);//被调用时得到了某个变量的地址
    int i=0;f(&i);//在函数里面可以通过这个指针访问外面这个i
  • “*” 是一个单目运算符, 用来访问指针的值所表示的地址上的变量,可以做右值也可以做左值。
  • int k = *p;*p=k+1;

应用场景
1.交换两个变量的值

void swap(int *pa,int *pb)
{
	int t=*pa;
	*pa=*pb;
	*pb=t;
}

2.函数返回多个值,某些值只能通过指针返回
返回的参数实际上是需要保存带回的结果的变量

  • 函数返回运算的状态, 结果通过指针返回
  • 常用的套路是让函数返回特殊的不属于有效范围内的值来表示出错:-1 或0 ( 在文件操作会看到大量的例子)
  • 但是当任何数值都是有效的可能结果时, 就得分开返回了
  • 地址变量没被赋值前(未得到实际变量地址)不能通过其访问任何数据、变量。
    数组参数
    以下四种函数原型是等价的

int sum(int *ar, int n);
int sum(int * , int);
int sum(int ar[], int n);
int sum(int [ ] , int);

数组变量是特殊的指针

  • 数组变量本身表达地址, 所以
    • int a[10]; int*p=a; / / 无需用&取地址
    • 但是数组的单元表达的是变量, 需要用& 取地址
    • a==&a[0]
  • “[ ]” 运算符可以对数组做, 也可以对指针做:
    • p[0]–>a[0]
  • *运算符可以对指针做, 也可以对数组做:
    • *a=25
  • 数组变量是const 的指针, 所以不能被赋值
    • int a[ ] < = = > int * const a

int * const q:指针是const,一旦得到某变量地址不再指向其他变量。
const int * p(int const * p):所指是const,不能对所指的值进行操作(只读),并不能使所指变量成为const,但该指针可以指向新的地址。
判断标志是const在 * 的前面还是后面
转换
总是可以把一个非const 的值转换成const 的

void f(const int* x) ;
int a=15 ;
f(&a);//ok
const int b = a ;

f(&b);//ok
b = a + 1 ; // Error!

  • 当要传递的参数的类型比地址大的以候, 这是常用的手段: 既能用比较少的字节数传递值一口参数, 又能避免函数对外面的变量的修改。
  • const数组必须通过初始化进行赋值(const int a[]={1,2,3,4,};),把数组传入函数时传递的是地址,可以修改数组的值,为保护数组可设置const数组。
    指针的类型
  • 无论指向什么类型, 所有的指针的大小都是一样的, 因为都是地址
  • 但是指向不同类型的指针是不能直接互相赋值的
  • 这是为了避免用错指针
    指针的类型转换
  • void* 表示不知道指向什么东西的指针
    • 计算时与char * 相同( 但不相通)
  • 指针也可以转换类型
    int * p = &i; void *q = (void * )p,
  • 这并没有改变p 所指的变量的类型, 而是让后人用不同的眼光通过p 看它所指的变量
    使用void*来表示指针的类型,从而忽略指针类型不同带来的作用

int a[] = {5, 15, 34, 54, 14, 2, 52, 72}; int *p = &a[5]; 则:
p[-2]的值是54

用指针来做什么

  • 需要传入较大的数据时用作参数
  • 传入数组后对数组做操作
  • 函数返回不止一个结果
    • 需要用函数来修改不止一个变量
  • 动态申请的内存

动态内存分配

malloc函数
#include <stdlib.h>
void* malloc(size_t size);

  • 向malloc申请的空间的大小是以字节为单位的
  • 返回的结果是void * , 需要类型转换为自己需要的类型
    (int*)malloc(n*sizeof(int))
  • 如果申请失败则返回0 , 或者叫做NULL
    ***free函数***跟malloc对应
#include<stdio.h>
#include<stdlib.h>

int main()
{
	void *p;
	int cnt=0;
	while(p=(malloc(100*1024*1024))){
		cnt++;
	}
	printf("分配了%d00MB的空间",cnt);
	free(p);
	return 0;
}

相邻两次malloc得到的空间一般不是连续的,malloc从空闲内存列表中寻找合适的空间进行分配。

得到的空间的实际大小一般大于你要求的大小,malloc以最小分配的空间作为基本单位分配空间。

malloc零长度会得到一个最小分配的空间。

对于以下代码段,正确的说法是:

char *p;
while (1)
{
p = malloc(1);
*p = 0;
}
A. 最终程序会因为没有没有空间了而退出
B. 最终程序会因为向0地址写入而退出
C. 程序会一直运行下去
D. 程序不能被编译

malloc在分配内存失败时并不会终止程序,而是返回NULL指针。而第5行代码试图向NULL指针位置写入数据,这会引起程序终止(通常操作系统会因为“段错误”而终止程序)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值