C指针笔记

基础要好,房子才能盖的牢固,才能盖的高。先把基础补一补,再多刷点算法题看看。
1.c语言指针必须要先赋值才能够使用,不赋值就使用指针的指向是未知的。
2.指针是存放地址的变量。
3.数组名是一个地址,可以直接赋值给指针。

int num[4] = {1,2,3,4};
int *pNum;
pNum = num;	//将数组地址值,赋值给指针。

pNum++; //指向数组的指针自加,自加一个元素长度的地址,指向下一个元素。

4.指针与常数加减,都是加减对应的元素。(就是指针+1:指向下一个数组元素,其余加减法也是以元素为最小的符号)

int *pNum2;
pNum2 = pNum+3; //pNum地址值指向数组最后一个元素4。

int count = pNum2-pNum; //结果为3,即num[0]和num[3]之间索引相减。3-0=3;(指针的算术运算只在同一数组内有意义,两个不同数组的指针运算结果不确定,可能会出错)

5.数组在声明之后只能一个一个的赋值,不能直接数组名放在等号左边赋值,因为等号左边必须是变量。

int array[3];
array = {1,2,3}; //这样赋值是错误的。

6.指针的算术加减运算是以指针的类型为基本单元,char指针+1就是加一个字节(char的长度1个字节)。int指针+1就是加四个字节(int的长度4个字节)。如下:

int main(){
    char charArr[7] 
    int intArr[7] = 
    
    char *pCharArr;
    char *pCharArr1;
    char *pCharArr2;
    char *pCharArr3;

    int *pIntArr;
    int *pIntArr1;
    int *pIntArr2;
    int *pIntArr3;

    pCharArr = charA
    pIntArr = intArr

    pCharArr1 = char
    pCharArr2 = char

    pIntArr1 = intAr
    pIntArr2 = intAr
    
}

在这里插入图片描述
7.c指针数组声明(就是数组元素都是指针)

int *num[3]; //声明一个名字是num的指针数组,数组中有三个int类型的指针元素,(同一指针数组中只能存放统一类型数据,数组中也是一样)

8.指针声明但不初始化时必须要加上数组的长度,指针声明并直接初始化时可以不用加数组长度。

char name[10]; //声明一个长度10个char元素的数组name,声明数组但不初始化必须加数组长度。
char address[] = {"abcdef"}; //声明一个数组并直接初始化,可以不加数组长度。

9.函数形参(指针除外)作用域只在函数内有效,函数间传值用函数返回值传递,或使用指针。

#include <stdio.h>
typedef unsigned char uint8_t;
extern void swapdata(uint8_t dat_x,uint8_t dat_y);

int main(){
    uint8_t x,y;

    printf("请输入x,y:\n");
    scanf("%d,%d",&x,&y);
    printf("交换前x=%d,y=%d\n",x,y);
    swapdata(x,y);
    printf("交换后x=%d,y=%d\n",x,y);
}

//函数的形参只在函数内有效,是函数创建的临时变量,离开函数就失效了。无法改变实参的值。
void swapdata(uint8_t dat_x,uint8_t dat_y){
    uint8_t temp;
    temp = dat_x;
    dat_x = dat_y;
    dat_y = temp;
}

在这里插入代码片

利用指针传递值,指针是指向数据的地址,指针指向的对应地址中保存着指针(*运算后取值后)的数据。
有点乱不知道怎么解释好了。

#include <stdio.h>
typedef unsigned char uint8_t;
extern void swapdata(uint8_t *dat_x,uint8_t *dat_y);

int main(){
    uint8_t x,y;
    uint8_t *p_x,*p_y; //指针作为中间参数,好像不占有空间,让指针指向x和y。一个数据可以有一个指针,我还以为是重新又创建了一个中间变量,其实不是。一个数据可以创建一个指针指向他。

    printf("请输入x,y:\n");
    scanf("%d,%d",&x,&y);
    p_x = &x; //将指针变量指向x和y。
    p_y = &y;

    printf("交换前x=%d,y=%d\n",x,y);
    swapdata(p_x,p_y);
    printf("交换后x=%d,y=%d\n",x,y);
}

//指针类型的参数就是地址,所以使用函数时,传递的是地址。
void swapdata(uint8_t *dat_x,uint8_t *dat_y){
    uint8_t temp;
    temp = *dat_x;
    *dat_x = *dat_y; //将指针指向的数据,赋值给另外一个指针指向的数据。
    *dat_y = temp; //同理,给指针参数赋值。
}

10.主函数需要将实参作为指针传递给被调用函数,被调用函数才可能改变实际参数。

void test(int *arg1,char *arg2); //像这样的函数,参数是指针。

11.数组名是地址,可以将其直接赋值给指针。如下

int arr[] = {1,2,3}; //数组名arr是个地址
int *p_arr; //*后面指针名也是个地址,(*地址)声明一个类型的指针。
p_arr = arr; //完成指针初始化,将指针指向数组首地址。

12.结构体中有数组的话,声明结构体时不用再另外加括号。按照顺序声明每个数据即可。
(结构体数组,一个数组里面都是结构体,哈哈哈,结构体里面还可以再有数组,无限套娃。)

typedef struct 
{
    uint8_t data;
    uint8_t name;
    uint8_t someData[DATA_MAX]; //这是个结构体中的数组。声明时直接按照元素索引顺序排列即可,无需另外加括号,结构体就是一段连续的存储单元,存储着一组数据。
    uint8_t age;
}MY_OWN_STRUCT;

//声明结构体数组
MY_OWN_STRUCT my_struct[STRUCT_MAX] = {
    {0x11,0x12,0x13,0x13,0x13,18},
    {0x22,0x13,0x14,0x14,0x14,25},
    {0x33,0x14,0x15,0x15,0x15,50}
};

uint8_t test = mystruct[1].data; //调用结构体中数据
uint8_t arr = mystruct[2].someData[1]; //调用结构体中的数组元素

13.普通变量作为函数参数传递时,把实参的值传递给形参,也就是说形参值是实参值的拷贝,形参和实参虽然是同样的值,但存储在不同的内存空间中。在被调用函数中,是对形参的操作,而对实参没有进行任何操作。普通变量作为函数参数时,实参值不会进行变化。而指针变量作为函数参数时,通过指针变量的值传递,是让形参指向实参变量指向的变量,通过指针变量的值传递后,形参变量和实参变量指向同一个变量。所以,在被调用函数中,对形参的操作,就是对其指向变量的操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值