C(指针与结构体)和C++(引用与布尔)

本文详细介绍了C和C++中的指针概念,包括指针与指针变量的区别,值传递的原理,数组偏移的应用,malloc内存管理,结构体与结构体指针,C++中引用的使用以及一级和二级指针的区别。同时提及了布尔类型的值表示。
摘要由CSDN通过智能技术生成

一、C

1.指针(间接访问)

指针与指针变量是两个概念,一个变量的地址称为该变量的“指针”。
例如,地址2000是变量i的指针。
如果有一个变量专门用来存放另一变量的地址(即指针),那么称它为“指针变量”。
#include <stdio.h>

int main(void){
    int i = 5;
    int *p;
    p = &i;
    printf("%d",*p);
}

在这里插入图片描述

1).值传递

void change(int *j){
    *j = 10;
}

int main(void){
    int i = 5;
    printf("%d\n",i);  //5
    change(&i);
    printf("%d",i);    //10
}

2)偏移

数组名内存储了数组的起始地址

void change(char *q){
    *q = 'H';
    *(q+1) = 'E';
    q[2] = 'L';
}

int main(void){
    char a[10] = "hello";
    char *p = a;	
    change(a);   //数组名作为实参传递给子函数,弱化为指针
    puts(p);	//HELlo
    puts(p+1);	//ELlo
    printf("%c",*(p+1));	//E
}

3)malloc

int main(void){
    char *p;
    p = (char *)malloc(20*sizeof(char));    //malloc返回的是void* 代表无类型指针,不会偏移
    strcpy(p, "malloc malloc");
    puts(p);		//malloc malloc
    free(p);
    return 0;
}

释放申请空间必须是malloc返回的地址

栈空间和堆空间差异

栈空间调用完会被释放

char* change(){
    char a[20] = "hello world";
    char *q;
    q = a;
    puts(q);         //hello world
    return q;
}

int main(void) {
    char *p ;
    p = change();
    puts(p);		//null
    return 0;
}

改用堆空间

char* getMalloc(char *q){
    q = (char*)malloc(20*sizeof(char));
    strcpy(q,"hello world");
    return q;
}

int main(void) {
    char *p ;
    p = getMalloc(p);
    puts(p);      //hello world
    free(p);
    return 0;
}

2.结构体

struct student{
    double score;
    char s;
    short age;
};
int main(){
    struct student stu ;
    printf("%zu",sizeof(stu)); //16  //%zu格式说明符来打印size_t类型的值
    return 0;
}

考虑到对齐要求,结构体 student 的大小是 16 字节。这是因为结构体的大小通常是其成员中最大类型的大小的倍数, double 类型通常需要8字节对齐,char 类型需要1字节对齐,编译器会在 char 类型变量后面填充一个字节,以确保 short 类型变量 age 能够正确对齐到 2 字节的边界,而 short 类型可能需要2字节对齐。
(两个小单位比最大整数倍要小,可以连在一起)

1)结构体指针

一个结构体变量的指针就是该变量所占据的内存段的起始地址

struct student{
    int id;
    char name[20];
    char sex;
};

int main(){
    struct student s = {1001,"zs",'F'};
    struct student stu[2] = {{1000,"zs",'F'},{1002,"ls",'M'}};
    struct student *p ;
    p = &s;
    printf("%d %s %c\n",p->id,p->name,p->sex);   //1001 zs F
    p = stu + 1;
    printf("%d %s %c",p->id,p->name,p->sex);     //1002 ls M
}

2)typedef 取别名

typedef struct student{
    int id;
    char name[20];
    char sex;
}stu,*pstu;

typedef int INT;
int main(){
    stu s = {1001,"zs",'F'};
    pstu q = &s;
    printf("%d %s %c\n",q->id,q->name,q->sex);   //1001 zs F

    INT num = 10;
    printf("%d",num);		//10
    return 0;
}
*pstu结构体指针  等价于struct student *

二、C++

1.引用’&’

子函数内修改主函数的一级指针变量
错误代码

void test(int *a, int *b){
    a = b;
}

int main(){
    int *p = NULL;
    int i = 10;
    int *q = &i;
    test(p, q);
    printf("%d",*p);
}

正确代码

void test(int *&a, int *b){
    a = b;
}

int main(){
    int *p = NULL;
    int i = 10;
    int *q = &i;
    test(p, q);
    printf("%d",*p);		//10
}
原因:C语言中的参数传递是按值传递的。
	 函数调用时,实参的值会被拷贝到形参中,函数内部对形参的修改不会影响到实参本身
	 向函数传递一个指针时,实际上是将指针的副本传递给了函数,而不是指针所指向的内容。因此,对指针的修改只会在函数内部生效,不会影响到函数外部的指针。

用C语言二级指针

void test(int **a , int *b){
    printf("%p\n",&(*a));		//0x7ffcbccbdef0
    printf("%p\n",*a);			//(nil)
    *a = b;
}

int main(){
    int *p = NULL;
    int i = 10;
    int *q = &i;
    printf("%p\n",p);		//(nil)
    printf("%p\n",&p);		//0x7ffcbccbdef0
    printf("%p\n",&i);		//0x7ffcbccbdeec   
    test(&p,q);
    printf("%d\n",*p);		//10
    printf("%p",q);      	//0x7ffcbccbdeec
    return 0;
}

test中传入的是(def0,deec),a为二级指针,*a是对def0地址取值为null,赋为deec

2.布尔类型

布尔类型也是有值的,true 为0,false为1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值