C语言学习笔记(十二):一维字符数组传参与高级指针应用
一、一维字符数组与指针
1. 字符数组本质
在C语言中:
字符串本质上是:
以'\0'结尾的一维字符数组。
例如:
char str[]="hello";内存结构:
h e l l o \0数组名:
str表示:
数组首元素的地址。
也就是:
&str[0]二、一维字符数组传参
1. 数组作为函数参数
例如:
void print(char str[]) { }实际上等价于:
void print(char *str) { }原因:
数组传参时,数组名会退化为指针。
例如:
#include<stdio.h> void print(char *p) { printf("%s\n",p); } int main() { char str[]="hello"; print(str); return 0; }输出:
hello执行过程:
str数组 ↓ 首地址 ↓ 传递给指针p ↓ 访问字符串三、利用指针计算字符串长度
C语言中的:
strlen()作用:
计算字符串长度。
例如:
strlen("hello")结果:
5但是我们可以自己实现。
1. 使用数组下标方式
代码:
int mystrlen(char str[]) { int i=0; while(str[i]!='\0') { i++; } return i; }执行过程:
str[0] str[1] str[2] ... 直到'\0'2. 使用指针方式
代码:
int mystrlen(char *p) { int len=0; while(*p!='\0') { p++; len++; } return len; }执行过程:
开始:
p → h移动:
p++直到:
p → '\0'这种方式更加接近C语言底层实现。
四、字符串复制函数 mystrcpy
C语言库函数:
strcpy()作用:
将一个字符串复制到另一个字符数组。
例如:
char a[20]; char b[]="hello"; strcpy(a,b);结果:
a="hello"自己实现:
void mystrcpy(char *dest,char *src) { while(*src!='\0') { *dest=*src; dest++; src++; } *dest='\0'; }执行过程:
源字符串:
src h e l l o \0目标:
dest _ _ _ _ _逐个复制:
h e l l o \0五、字符串连接函数 mystrcat
C语言:
strcat()作用:
连接两个字符串。
例如:
hello + world结果:
helloworld实现思路:
找到目标字符串末尾;
从末尾开始复制第二个字符串。
代码:
void mystrcat(char *dest,char *src) { while(*dest!='\0') { dest++; } while(*src!='\0') { *dest=*src; dest++; src++; } *dest='\0'; }六、字符串比较函数 mystrcmp
C语言:
strcmp()用于比较两个字符串。
比较规则:
按照字符ASCII码比较。
例如:
abc abd比较:
a=a b=b c<d所以:
abc < abd实现:
int mystrcmp(char *s1,char *s2) { while(*s1==*s2) { if(*s1=='\0') return 0; s1++; s2++; } return *s1-*s2; }返回结果:
0:相等
大于0:s1大
小于0:s1小
七、字符串倒置
字符串倒置:
例如:
原字符串:
hello变成:
olleh实现思路:
使用两个指针:
start end ↓ ↓ h e l l o交换:
h ↔ o e ↔ l代码:
void reverse(char *str) { char temp; char *start=str; char *end=str; while(*end!='\0') { end++; } end--; while(start<end) { temp=*start; *start=*end; *end=temp; start++; end--; } }八、指针函数
1. 什么是指针函数?
指针函数:
返回值为指针类型的函数。
例如:
int *fun(int x,int y);表示:
函数返回:
int *类型。
示例:
int *fun() { static int a=10; return &a; }调用:
int *p; p=fun();注意:
函数:
不能返回局部变量地址。
错误:
int *fun() { int a=10; return &a; }原因:
函数结束后:
局部变量空间被释放。
指针会变成野指针。
九、函数指针
1. 什么是函数指针?
函数指针:
指针指向一个函数。
例如:
int (*p)(int,int);表示:
p是一个指向函数的指针。
普通指针:
指向变量函数指针:
指向函数2. 函数指针使用
例如:
定义函数:
int add(int a,int b) { return a+b; }定义函数指针:
int (*p)(int,int);让p指向add:
p=add;调用:
p(10,20);等价:
add(10,20);十、指针函数和函数指针区别
| 类型 | 含义 |
|---|---|
| 指针函数 | 函数返回指针 |
| 函数指针 | 指针指向函数 |
简单理解:
指针函数: 函数 → 返回指针 函数指针: 指针 → 指向函数十一、const修饰指针
const:
含义:
readonly(只读)
表示不能修改。
1. const int *p
等价:
int const *p;例如:
const int *p;表示:
p可以改变
例如:
p=&b;允许。
不能通过p修改数据
错误:
*p=100;总结:
指针可变 数据不可变2. int *const p
表示:
指针本身不可改变。
例如:
int *const p=&a;允许:
*p=100;不允许:
p=&b;总结:
指针不可变 数据可变3. const int *const p
表示:
指针和数据都不能改变。
例如:
const int *const p=&a;特点:
不能:
p=&b;也不能:
*p=100;总结:
指针不可变 数据不可变十二、const指针总结表
| 定义 | 指针 | 数据 |
|---|---|---|
| const int *p | 可变 | 不可变 |
| int const *p | 可变 | 不可变 |
| int *const p | 不可变 | 可变 |
| const int *const p | 不可变 | 不可变 |
