C语言的灵魂:指针
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
(1) int *ptr;
(2) char *ptr;
(3) int **ptr;
(4) int (*ptr)[3];
(5) int *(*ptr)[4];
1.指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
(1) int *ptr; //指针的类型是int*
(2) char *ptr; //指针的类型是char*
(3) int **ptr; //指针的类型是int**
(4) int (*ptr)[3]; //指针的类型是int(*)[3]
(5) int *(*ptr)[4]; //指针的类型是int*(*)[4]
2.指针所指向的类型
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。
(1) int *ptr; //指针所指向的类型是int
(2) char *ptr; //指针所指向的类型是char
(3) int **ptr; //指针所指向的类型是int*
(4) int (*ptr)[3]; //指针所指向的类型是int()[3]
(5) int *(*ptr)[4]; //指针所指向的类型是int*()[4]
3.指针的值
指针所指向的内存区或地址
4.指针本身所占的内存大小
只要用函数sizeof(指针的类型)
int ptr;
sizeof(int);
运算符
&是取地址运算符,*是间接运算符。
“ & ”和“ * ”都是右结合的。
假设有变量 x = 10
则*&x 的含义是:
先获取变量 x 的地址,再获取地址中的内容。
因为“&”和“*”互为逆运算,所以 x = *&x。
初始化初始化:
利用取地址获取 x 的地址,在指针变量 px 定义时,赋值给 px
int x;
int *px = &x;
定义指针变量,分别赋值“NULL”和“0”
int *p1= NULL, *p2 = 0;
此时的“0”含义并不是数字“0”,而是 NULL 的字符码值。
这种初始化的方式表示其目前还未指向任何对象。
int a = 100, b;
int *p = &a;
int *p2 = NULL;
p2 = &a;
printf("%d\n", *p2);
printf("%p\n", p);
printf("%p\n", &a);
printf("%d\n", *p);
C 指针的算术运算:
int a[] = {
1, 2, 100, 4, 5, 6, 7};
int *p = a;
printf("%d\n", *p);
printf("%d\n", *p++);
printf("%d\n", *p);
printf("%d\n", *p);
printf("%d\n", *++p);
printf("%d\n", ++(*p++));
printf("%d\n", *p);
printf("%d\n", *(p + 3));
printf("%d\n", *p + 1);
需要明确一个优先级顺序:()>[]>*
C 指针数组: int *p1[5];
数组存储指向 int 或 char 或其他数据类型的指针。
一个数组的元素均为指针类型数据,称为指针数组。
C 数组指针: int (*p2)[5]; => *(p2[5]);
如果一个指针指向了数组,我们就称它为 数组指针。
int var[3] = {
10, 100, 200};
int i, *ptr[3];//指针数组
int (*ptr2)[3];//数组指针
ptr2 = &var;
for (i = 0; i < 3; i++)
{
ptr[i] = &var[i]; /* 赋值为整数的地址 */
}
for ( i = 0; i < 3; i++){
printf("Value of var[%d] = %d\n", i, *ptr[i] );
printf("Value of var[%d] = %d\n", i, (*ptr2)[i] );
}
}
char name[10][10]= {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
//char name[0];
//char *p = name[0];
const char *names[4] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
int i = 0;
for ( i = 0; i < 4; i++){
printf("Value of names[%d] = %s\n", i, names[i] );
}
C 指针函数:*p(int, int)
它的本质是一个函数,不过它的返回值是一个指针。
C 函数指针:(*p)(int, int)
函数指针是指向函数的指针。
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。
int max(int a,int b){
if(a>b)
return a;
else
return b;
}
int *fun(int n){
static int arr[100];//静态变量
//C 不支持在调用函数时返回局部变量的地址,除非定义局部变量为 static 变量。
//static 变量的值存放在内存中的静态数据区,不会随着函数执行的结束而被清除,故能返回其地址。
int i;
for (i = 0; i < n;i++){
arr[i] = i;
}
return arr;//返回了指针
}```
```cpp
int (*p)(int, int) = &max;//函数指针
int a = 10, b = 5;
printf("最大数为:%d\n", p(a, b));
//等价于max(a,b);
int n = 10;
int *p1;
p1 = fun(n);
int i;
for (i = 0; i < n;i++){
printf("%d\n", *(p1 + i));
}
编写一个函数实现:将字符串中的字符以逆序形式存放。
在main函数中输入这个字符串,调用函数逆序存放,输出变化后的字符串
(要求:形参是指针类型变量)。
交换函数
void swap1(int a,int b){
int t;
if(a<b){
t = a;
a = b;
b = t;
}
printf("%d %d\n", a, b);
}
void swap(int *a,int *b){
int t;
if(*a<*b){
t = *a;
*a = *b;
*b = t;
}
}
int main(){
int a = 100, b = 200;
printf("%d %d\n", a, b);
swap1(a, b);
printf("%d %d\n", a, b);
swap(&a, &b);
printf("%d %d\n", a, b);
}
#include<string.h>
void func(char *a,int n){
char temp;
for (int i = 0; i < n / 2;i++){
temp = *(a + i);
*(a + i) = *(a + n - 1 - i );
//0 ...n-1
*(a + n - i - 1) = temp;
}
puts(a);
}
int strlen(char *a){
int i = 0;
while(a[i]!='\0'){
i++;
}
return i;
}
int main(){
char a[100];
gets(a);
int len = strlen(a);
printf("%d\n", len);
func(a, len);
return 0;
}