一、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