------Java培训、Android培训、iOS培训、.Net培训 期待与您交流! -------
指针在C语言中的重要性不言而喻,本篇将通过一些实例来带你掌握指针的使用方法。
先来看看我们的第一段小代码,通过这个来了解一下指针的基本使用
#include <stdio.h>
int main()
{
int a = 20;
int *p;
p = &a;
printf("%d\n",*p);
return 0;
}
1.指针的定义
类名标识符 *指针变量名;
2.指针赋值和取值
在int *p;这句代码里,* 是指针的标志;指针里存储的是变量的地址,也就是p = &a;,这时,我们通常说指针p指向了变量a;当需要将值取出来时,使用*p,表示访问指针p所指向的存储空间(a的地址)并将其值取出。
上面的指针是先定义后赋值,当然在定义指针的同时赋值也是可以的,int *p =&a;。
3.利用指针修改变量的值
要想通过指针改变a的值,只需要 *p = 10;这句就可以,表示访问变量p所指向的变量(a),并将它的值进行修改。
4.使用指针的注意点
(1)p是指针名,存放的是地址,如果写 p= 1000;这样是错误的,可以取出和修改变量值的是 *p。
int *p; *p = 100; 这样写编译和链接时不会出错,但是运行时会报错,原因是:p并没有指向任何存储空间,是个空指针,怎么利用*p修改值呢?
(2)打印p的值
printf("%p-%d\n",p,*p);
结果
0x7fff5f09ec38-20
p的值是它存储的地址,可以利用%p来输出(3)指针类型
指针的类型是不可以胡乱定义的,int型数据对应int型指针,如果乱用里面的值是不对的
(4)清空指针
p = 0;或p = NULL;
指针应用实例
1. 指针与数组
/*
1> 设计一个函数:int arraySum(int *p, int n),求一维数组a前n个数的和。
*/
int arraySum(int *p, int n)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += p[i];
}
return sum;
}
int main()
{
int a[5] = {1,2,3,4,5};
int sum = arraySum(a,3);
printf("%d\n",sum);
return 0;
}
这个函数需要传入的实参是个int型的指针,也就是形参需要传入地址,而数组a就表示数组的地址,所以这里直接用arraySum(a,3),不用加 &符。
2. 指针与字符串
char *in = "hello";
char *h = "hello";
printf("%p\n%p\n",in,h);
看上面的代码,结果是
0x10fb25f86
0x10fb25f86
这也就说明利用定义不同名字的指针指向一个同一个字符串常量,并没有开辟新的空间,他们指向的是同一存储空间。
适用场合:字符串的内容不需要修改,而且这个字符串经常使用,不用频繁的开辟和销毁内存空间,节省内存,性能上更好
我们来做一个小练习
* 编写一个int string_len(char *s),返回字符串s的字符长度
#include <stdio.h>
#include <string.h>
int string_len(char *s)
{
return strlen(s);
}
int main()
{
char *in = "这里是字符串小练习";
int len = string_len(in);
printf("%d\n",len);
return 0;
}
结果是:27
注意了一个汉字占3个字节,'\0'不计算长度
3. 返回指针的函数
#include <stdio.h>
char *test()
{
return "返回指针的函数练习";
}
int main()
{
char *c = test();
printf("%s\n",c);
return 0;
}
4. 指向函数的指针
#include <stdio.h>
typedef int (*myint)(int,int);
int sum(int a, int b)
{
return a + b;
}
int minus(int a ,int b)
{
return a - b;
}
int main()
{
//定义指向函数的指针
myint p;
myint p1;
p = sum;
p1 = minus;
printf("和是%d,差是%d\n",(*p)(10,5),(*p1)(10,5));
return 0;
}
结果是:
和是15,差是5
typedef int (*myint)(int,int); 这一句是自定义一个可以传入两个参数的指针类型。给类型起别名,包括基本类型和结构体类型,枚举类型等等
typedef 类型 别名typedef struct Person
{
int age;
} * PersonPoint;
这是定义一个指向结构体指针的新类型,在使用时,直接利用PersonPoint p;就可以定义一个指向该结构体的指针p
(2)条件编译
条件编译,满足条件的才会编译,效率更高
#include <stdio.h>
#define A 10
int main()
{
#if (A == 10)
printf("A是10\n");
#elif (A == 5)
printf("A是5\n");
#else
printf("A是其他值\n");
#endif
return 0;
}
条件编译和宏定义结合使用,在实际开发中,编写头文件时非常有用
#ifndef LISI_H
#define LISI_H
int sum(int a,int b);
#endif
作用是:只编译一次,提高编译的效率,要注意定义的宏名通常以文件名命名
(3) extern和 static
对函数:
extern的作用:
完整的定义外部函数
完整的声明外部函数
但是默认情况下,所有的函数都是外部函数,所以可以省略
整个项目中都不允许有同名的外部函数
static的作用
定义内部函数(只能在本文件调用,其他文件无法无法调用)
声明内部函数
不可省略
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
对变量:
全局变量分两种:
外部变量:定义的变量能被本文件和其他文件访问(默认情况下,所有的全局变量都是外部变量)
内部变量:定义的变量只能被本文件访问
全局变量不管定义多少个,都不会报错,所有的都是同一个
不同文件的同名外部变量,都代表同一个变量
extern(定义外部变量不加extern)的作用:
声明外部变量
static的作用
定义内部变量
static 修饰的局部变量,
生命周期变长,程序结束时销毁
但是它的作用域并没有改变
对性能优化有益,经常使用的变量可以如此定义
好了,C语言的基础篇到这里就结束了,下面要开始OC篇了