如何分析C/C++指针、函数、结构体和共用体,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
指针
变量与地址
变量给谁用的?
变量是对某一块空间的抽象命名。
变量名就是你抽象出来的某块空间的别名。
指针就是地址。指向某个地址。
指针与指针变量
指针是指向某块地址。指针(地址)是常量。
指针变量是可以发生变化的。
#include <stdio.h>int main(){ int i = 1; int *p = &i; printf("i = %d \n", i); printf("&i = %p \n", &i); printf(" p = %p \n", p); printf("&p = %p \n", &p); printf("*p = %d \n", *p); // 为什么不用char* p = &i; //TYPE NAME = VALUE //int* p = &i; //int i = 1;}
直接访问间接访问
占内存空间
都是8字节,linux 64 位中。
空指针 野指针 空类型
int * i= NULL;
指针运算
两个指针同时指向一个数组。++ 、--、比较、关系、&、*
指针与一维数组
数组名和 指针的区别?
a是数组名字是一个表示地址的常量。
指针是一个变量。
a++;
p++;
#include <stdio.h>int main(){ int a[3] = {1,2,3}; int *p = a; int i; for(i = 0;i < sizeof(a)/sizeof(*a); i++) { printf("%d %d %d %d \n",a[i],*(a+i),p[i],*(p+i)); // a[i] printf("%p %p %p %p \n",a+i, &a[i],p+i, p+i); // &a[i] } printf("\n");}
这里代码体现什么是指针常量什么是指针变量?
#include <stdio.h>int main(){ int a[3]; int i; int *p = a; for(i = 0;i < sizeof(a)/sizeof(*a); i++) { printf("%p -> %d\n",&a[i],a[i]); } for(i = 0;i <sizeof(a)/sizeof(*a); i++) { scanf("%d",p++); //p = a; for(i = 0;i < sizeof(a)/sizeof(*a); i++,p++) { printf("%p -> %d\n",p,*p); printf("\n");}
指针与二维数组
#include <stdio.h>#include <stdlib.h>int main(){ int a[2][3] = {1,2,3,4,5,9}; int i,j; int *p;//(W) p = a; //wall等号右边a是在行间跳转的指针 // 等号左边是列间跳转的指针 p = *(a+0); //p = &a[0][0];/int main(){ #if 0 // cosnt修饰常规变量的使用特点 // 这个警告已经构成error const float pi = 1.14159; // pi = 9999.2; float *p = π // initialization discards ‘const' qualifier from pointer target type [enabled by default] *p = 1223.333333; // 修改方法 const float *p = π printf("%f\n",pi); // 1223.333333 printf("%f\n",*p); #endif // 常量指针:指针的指向可以发生变化但是指针所指向的目标值是不能变化的 // const *p // 值不能变 // 指向可以发生变化 int i = 1; const int *p1 = &i; int j = 88;//T i= 10; //F *p1 = 99;//T p1 = &j; printf("%d\n",i); printf("%d\n",*p1); // 指针常量:指针的指向不能发生变化,指针所指向的目标变量的值可以发生变化。 int j= 100; int * const p1 = &i;//T *p1 = 10;//F p1 = &j; //const 左右都有 指向和值都不能变 int num = 10; const int* const p3 = # // *p3 = 99; // p3 = &i; exit(0);}
指针数组和数组指针的区别
数组指针
#include <stdio.h>#include <stdlib.h>int main(){ // 数组指针 int a[2][3] = {1,2,3,4,5,9}; int i,j; int *p = *a; int (*q)[3] = a; //printf("%d \n", *a); // a[0][0]的地址 //printf("%d \n", **a); //1 #if 0 // printf("%d \n",*p);//q //int *p = *a; //printf("%d \n",*p); //q // int (*q)[3] = a+1; // printf("%d \n",**q); // 4 printf("\n"); for(i = 0;i < 2; i++) { for(j = 0; j < 3; j++) { // printf("%p->%d\n",*(a+i)+j,*(*(a+i)+j)); printf("%p->%d\n",*(q+i)+j,*(*(q+i)+j)); } printf("\n"); } #endif }
指针数组:
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ char *name[5] ={"english","math","cpp","teacher","computer"}; int i,j; for(i = 0; i < 5; i++) { puts(name[i]); } for(i = 0; i < 5 ;i++) { int k = i; for(j = i+1;j < 5; j++) { if(strcmp(name[k],name[j]) > 0) { k = j; } } if(k != i) { char *tmp = name[i]; name[i] = name[k]; name[k] = tmp; printf("排序后:\n"); exit(0);}
指针和函数
函数:
echo $? // 显示上个命令的返回值
#include <iostream>using namespace std;//void func1(int *a,int n)void func1(int* a,int n,int *b){cout << "== b =" << *b<< endl; // 1for(int i = 0;i < n; i++){printf("%d ",*(a+i));}printf("\n");return ;}int main(int argc, char** argv) {int arr[3] = {1,2,3};func1(arr,3,&arr[1]);//&(*(ar+1))return 0;
用指针与一维数组的使用:
void func2(int *p,int n){int m = n / 2;for(int i = 0;m--;i ++){int j = n - i -1;int tmp = *(p+i);*(p+i) = *(p+j);*(p+j) = tmp;}}int main(int argc, char** argv) {int arr[] = {1,2,3,6,4,2,38,4,2,23};//func1(arr,3,&arr[1]);//&(*(ar+1))func2(arr,10);for(int i = 0;i < 10;i ++)cout << arr[i] << ' ' ;cout <<endl;return 0;
函数与二维数组:
#include <iostream>using namespace std;void func(int *p,int n){for(int i = 0;i < n; i++){cout << *p << ' ';p++;}}void print_arr(int (*p)[3])for(int i = 0;i < 3;i++)for(int j = 0;j < 3;j++){cout << *(*(p+i)+j) << ' ';}cout<< endl;int main(int argc, char** argv) {int arr[3][3] = {1,2,3,6,4,2,38,4,2};func(arr[0],9); // *arr &arr[0][0] arr[0]// 这里func(arr,9) 形参是int *p 就报错 p是一个列指针,二维数组不一样 print_arr(arr);return 0;
案例使用二维数组传参
float average_score(int *a,int n){float sum = 0.0;for(int i = 0;i < n; i++){sum += *(a+i);}return sum/n;}void find_num(int(*p)[3],int num){for(int i = 0;i < 3 ;i++)printf("%d ",*(*(p+num) + i));cout << endl;return ;}int main(int argc, char** argv) {int arr[3][3] = {1,2,3,6,4,2,38,4,2};float ave = 0.0;ave = average_score(*arr,9);printf("%f \n",ave);find_num(arr,0);return 0;}
函数与指针关系的详细剖析
指针函数
返回值 * 函数名(参数)
#if 0void find_num(int(*p)[3],int num){for(int i = 0;i < 3 ;i++)printf("%d ",*(*(p+num) + i));cout << endl;return ;}#else int * find_num(int(*p)[3],int num)return *(p+num);#endifint main(int argc, char** argv) {int arr[3][3] = {1,2,3,6,4,2,38,4,2};float ave = 0.0;ave = average_score(*arr,9);printf("%f \n",ave);int * res;res = find_num(arr,0);if(res != NULL){for(int i = 0;i < 3;i++)printf("%d ",res[i]);cout <<endl;}else printf("can not find\n");return 0;
函数指针
#include <iostream>using namespace std;int add(int a,int b){return a+b;} int sub(int a,int b){return a-b;}int main(int argc, char** argv) {int a = 2, b = 3;int (*p)(int,int);int (*q)(int,int);int ret;p = add;q = sub;printf("%d \n",p(a,b));printf("%d \n",q(a,b));return 0;}
回调函数
函数指针数组
类型 (*数组名[下标])(形参);
#include <iostream>using namespace std;int add(int a,int b){return a+b;} int sub(int a,int b){return a-b;}int main(int argc, char** argv) {int a = 2, b = 3;int (*funcp[2])(int,int);int ret;funcp[0] = add;funcp[1] = sub;for(int i = 0;i < 2; i++){ret = funcp[i](a,b);printf("%d \n",ret);}return 0;}
指向指针函数的函数指针数组
数组存放指针,指针指向函数,函数返回值是指针类型。
结构体
产生的意义
类型描述
嵌套定义
定义变量、初始化及引用
占用内存大小
定义和使用:
#include <iostream>using namespace std;#define NAMESIZE 100struct simp_st {int i,j;float f;char ch;};struct birthday_stint year,month,day;struct student_stint id;char name[NAMESIZE];struct birthday_st birthday;int math;int chinese;int main(int argc, char** argv) struct student_st stu = {10011,"Alan",{3011,22,11},22,54};struct student_st *p = &stu;printf("%d %s %d-%d-%d %d %d \n",stu.id,stu.name,stu.birthday.year,stu.birthday.month,stu.birthday.day,stu.math,stu.chinese);printf("%d %s %d-%d-%d %d %d \n",p->id,p->name,p->birthday.year,p->birthday.month,p->birthday.day,p->math,p->chinese);struct student_st stu[2] = {{10011,"Alan",{3011,22,11},22,54},{10012,"salay",{2021,2,12},88,66}};struct student_st *p = &stu[0];// &stu[0] stufor(int i = 0;i < 2;i++,p++){printf("%d %s %d-%d-%d %d %d \n",p->id,p->name,p->birthday.year,p->birthday.month,p->birthday.day,p->math,p->chinese);}return 0;}
内存对齐问题
addr/sizeof()
构造类型-结构体内存问题及函数传参
为后面linux高级铺垫。
可以实现一个学生管理系统。
产生及意义
类型描述
嵌套定义
定义变量
占用内存大小
函数传参
位域
union 名{数据类型 成员名1;数据类型 成员名2;};
枚举类型
enum 名{成员1;成员2;成员3;}
C语言是什么
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语言可以以简易的方式编译、处理低级存储器。
关于如何分析C/C++指针、函数、结构体和共用体问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。