时间:2022-04-29 10:08:13 | 栏目: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];//*(a+0),*a; printf("%p->%p \n", a, a + 1); // printf("%p -> %d \n\n",p,*p); // for(i = 0; i < 6; i++,p++) { // printf("%d ",*p); // } // 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",*(a+i)+j,*(*(a+i)+j)); //printf("%p->%d\n",a[i]+j,*(*(a+i)+j)); //printf("%d ",a[i][j]); } printf("\n"); } exit(0); }
指针与字符数组
#include <stdio.h> #include <stdlib.h> #include <string.h> // 字符指针和字符数组之间的使用 // // 练习 定义数组后定义指针 后面操作都用指针实现 int main() { #if 0 char* str = "hello"; // "hello" 串常量 printf("%d %d \n",sizeof(str),strlen(str));// 8 5 //strcpy(str,"world"); //err 为什么不可以?区分字符指针和字符数组的区别 :企图用"world" 覆盖串常量 str = "world"; puts(str); #endif char str[] = "hello"; printf("%d %d \n",sizeof(str),strlen(str));// 6 5 // (F) str = "hhhh"; // 数组名是一个地址常量怎么可能放到等号左边??? strcpy(str,"jjjj"); char str[] = "hello world"; char *p = str + 7; puts(p); exit(0); }
const与指针
#include <stdio.h> #include <stdlib.h> /* 常见const const int a; int const a; const int *p; // 常量指针 int const *p; int *const p; // 指针常量 const int *const p; define 不检查语法 */ 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 (*p)[3]; -> type name; -> int[3] *p; */ 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 *arr[3]; -> TYPE NAME; -> int *[3] arr; */ 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; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ /* 定义: int a[N] = {1,2,3,4,5,6}; int *p = a; -> a *a a[0] &a[3] p[i] p *p p+1 -> int* int int int * int int* int int* */ //void func1(int *a,int n) void func1(int* a,int n,int *b) { cout << "== b =" << *b<< endl; // 1 for(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; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ /* int a[M][N] = {......}; int *p = a; int (*q)[N] = a; -> a[i][j] *(a+i) a[i]+j p[i] *p int int * int * int int -> q[i][j] *q q p+3 q+2 int int* int(*)[N] int * int (*)[N] */ 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 0 void 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); #endif 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); 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 100 struct simp_st { int i,j; float f; char ch; }; struct birthday_st int year,month,day; struct student_st int 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] stu for(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; }