C语言(二)指针

本文详细介绍了C语言中指针的基本概念,包括指针变量的定义、初始化及内存占用情况。探讨了指针与数组、字符串及函数的关系,并通过实例演示了如何在实际编程中运用这些知识。

一、指针概述

1.简介

指针:其实就是地址。

指针变量:用来存储变量地址的变量。

2.初始化

1)先定义后初始化

int a =10;

int  *p;

p=&a;

2)定义并初始化

int a=10;

int *p =&a;

备注:在数据类型后,变量名称前的”*“是一个说明符,用来说明该变量是一个指针变量。

如果前面没有数据类型,如:*p,这里的”*“是一个指针运算符,用来取出指针变量所指向的变量。

3.指针变量的占用内存

在同一编译器环境下,所占用的内存是固定的,与指针变量的类型无关。

不同的编译器,指针变量的占用内存不同。

16位编译器->2字节,32位编译器->4字节 ,64位编译器->8字节


二、指针与数组

1.p是指针,a是数组
    1)如果p指向了一个数组元素,则p+1始终表示指向数组该元素的下一个元素。与编译器环境无关、与指向的数据类型无关。
        例如:p=&a[2], p+1=&a[3]
    2)对于不同类型的数组元素,p值的改变是不同的。如果数组元素为int型,p+1代表p的值加上2(在16位编译器环境下),不管p+1的值是多少,它始终保证刚好指向下一个元素

2.假设p的初始值是&a[0],那么:
    1)p+i和a+i,都可以表示元素a[i]的地址。它们都指向数组第i个元素的地址。
    2)*(p+i)和*(a+i),都表示数组元素a[i].
    3)虽然p+i和a+i都指向数组的第i个元素,但是二者还是有区别的。作为指针变量的p是可以改变自身的值,如p++。但是a是一个代表数组首地址的常量,同时也是一个数组的名字,它的值是不能改变的,即a++不合法。
3.用数组名作为函数实参时,实际上是把数组的首地址传递给形参数组,两个数组公用同一段内存空间。
4.在很多情况下,指针和数组是可以相互切换使用的,但并不能说指针就是数组。
5.例子
#include <stdio.h>
#include <string.h>
int main() {
	// 定义一个int类型的数组
	int a[4] = {1, 2, 3, 4};
	// 定义一个int类型的指针,并指向数组的第0个元素
	int *p = a;
	int i;
	for (i = 0; i < 4; i++) {
	    // 利用指针运算符*取出数组元素的值
	    int value = *(p+i);
	    printf("a[%d] = %d \n", i, value);
	}
	return 0;
}




三、指针与字符串
1.字符串可以看做一个特殊的字符数组,自然也就是一个数组。之所以特殊,是因为,它会在数组的末尾自动添加"\0",表示结尾。
2.指针和字符串的使用
#include <stdio.h>
int main() {
	char a[10]="china";
	char b[10];
	//b="china";	//因为b是数组的首地址,是一个常量,不能进行赋值运算
      
	char *c="china";
	char *d;
	d="china";//先声明,再初始化
	char *e="china";//e是一个指针变量,初始化的时候指向china
	e="uk";	//指针指向uk,修改了指针的地址
	//*e='m';//因为e指向的是一个常量,是不能修改的
	int leng =strlen(e);
	printf("%d\n",leng);	//长度:2
	printf("%c\n",*e);	//这里的e指向的是字符串的第一个字符。
	//printf("%s\n",*e);	//因为e指向的是uk的首字符“u”,不能以字符串形式输出。
	return 0;
}

3.遍历字符串
	char a[]="china";
	char *p=a;
	for(;*p !='\0';p++){
		printf("%c",*p);
	}
//输出结果:china

四、指针与函数
1.回顾一下
    int *p=12;
    p存储的是地址。
    *p是取出内存地址的值。
    p+1,下一个地址
    *(p+1),下一个地址的值
2.返回指针的函数
char * upper(char *str) {
    // 先保留最初的地址。因为等会str指向的位置会变来变去的。
    char *dest = str;
    // 如果还不是空字符
    while (*str != '\0') {
        // 如果是小写字母
        if (*str >= 'a' && *str <= 'z') {
            // 变为大写字母。小写和大写字母的ASCII值有个固定的差值
            *str -= 'a' - 'A';	//a-97 A-65
        }
        // 遍历下一个字符
        str++;	//下一个地址
    }
    // 返回字符串
    return dest;
}

3.指向函数的指针
为什么指针可以指向函数?
函数作为一段程序,在内存中也要占据部分存储空间,他也有一个起始地址,即函数的入口地址。既然函数有地址,指针变量就是用来存储地址的,因此,指针可以指向一个函数,函数名就是函数的地址。
4.例子
1)声明和初始化
#include <string.h>
#include <stdio.h>
int sum(int a, int b) {
	return a + b;
}
int main() {
	//int (*p)()=sum;//声明并初始化指针
	int (*p)(int, int)=sum;//建议使用这种
	//int (*p)(int number1,int number2)=sum;
	//int result = (*p)(1, 3);//用指针调用函数
	int result=p(1,3);
	printf("%d\n", result);
	return 0;
}
2)实际应用
#include <string.h>
#include <stdio.h>
#include <stdio.h>
// 减法运算
int minus(int a, int b) {
	return a - b;
}
// 加法运算
int sum(int a, int b) {
	return a + b;
}
//乘法运算
int mul(int a, int b) {
	return a * b;
}
// 这个counting函数是用来做a和b之间的计算,至于做加法还是减法运算,由函数的第1个参数决定
void counting(int (*p)(int, int), int a, int b) {
	int result = p(a, b);
	printf("计算结果为:%d\n", result);
}
int main() {
	// 进行加法运算
	counting(sum, 6, 4);//传入指针变量的名字p
	// 进行减法运算
	counting(minus, 6, 4);
	// 进行乘法运算
	counting(mul, 6, 4);
	return 0;
}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值