解析C/C++指針、函數(shù)、結(jié)構(gòu)體、共用體
指針
變量與地址
變量給誰用的?
變量是對某一塊空間的抽象命名。
變量名就是你抽象出來的某塊空間的別名。
指針就是地址。指向某個(gè)地址。
指針與指針變量
指針是指向某塊地址。指針(地址)是常量。
指針變量是可以發(fā)生變化的。

#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;
}直接訪問間接訪問

占內(nèi)存空間
都是8字節(jié),linux 64 位中。
空指針 野指針 空類型
int * i= NULL;
指針運(yùn)算
兩個(gè)指針同時(shí)指向一個(gè)數(shù)組。++ 、--、比較、關(guān)系、&、*
指針與一維數(shù)組
數(shù)組名和 指針的區(qū)別?
a是數(shù)組名字是一個(gè)表示地址的常量。
指針是一個(gè)變量。
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");
}這里代碼體現(xià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");
}指針與二維數(shù)組

#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是在行間跳轉(zhuǎn)的指針
// 等號左邊是列間跳轉(zhuǎn)的指針
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);
}指針與字符數(shù)組
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 字符指針和字符數(shù)組之間的使用
//
// 練習(xí) 定義數(shù)組后定義指針 后面操作都用指針實(shí)現(xiàn)
int main()
{
#if 0
char* str = "hello"; // "hello" 串常量
printf("%d %d \n",sizeof(str),strlen(str));// 8 5
//strcpy(str,"world"); //err 為什么不可以?區(qū)分字符指針和字符數(shù)組的區(qū)別 :企圖用"world" 覆蓋串常量
str = "world";
puts(str);
#endif
char str[] = "hello";
printf("%d %d \n",sizeof(str),strlen(str));// 6 5
// (F) str = "hhhh"; // 數(shù)組名是一個(gè)地址常量怎么可能放到等號左邊???
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修飾常規(guī)變量的使用特點(diǎn)
// 這個(gè)警告已經(jīng)構(gòu)成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
// 常量指針:指針的指向可以發(fā)生變化但是指針?biāo)赶虻哪繕?biāo)值是不能變化的
// const *p
// 值不能變
// 指向可以發(fā)生變化
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);
// 指針常量:指針的指向不能發(fā)生變化,指針?biāo)赶虻哪繕?biāo)變量的值可以發(fā)生變化。
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);
}指針數(shù)組和數(shù)組指針的區(qū)別
數(shù)組指針
#include <stdio.h>
#include <stdlib.h>
/*
數(shù)組指針: [存儲(chǔ)類型] 數(shù)據(jù)類型 (* 指針名) [下標(biāo)] = 值;
int (*p)[3]; -> type name; -> int[3] *p;
*/
int main()
{
// 數(shù)組指針
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
}
指針數(shù)組:
#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);
}指針和函數(shù)
函數(shù):
echo $? // 顯示上個(gè)命令的返回值

#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;用指針與一維數(shù)組的使用:
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;函數(shù)與二維數(shù)組:

#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 就報(bào)錯(cuò) p是一個(gè)列指針,二維數(shù)組不一樣
print_arr(arr);
return 0;案例使用二維數(shù)組傳參
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;
}函數(shù)與指針關(guān)系的詳細(xì)剖析
指針函數(shù)
返回值 * 函數(shù)名(參數(shù))
#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;函數(shù)指針
#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;
}
回調(diào)函數(shù)
函數(shù)指針數(shù)組
類型 (*數(shù)組名[下標(biāo)])(形參);
#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;
}指向指針函數(shù)的函數(shù)指針數(shù)組
數(shù)組存放指針,指針指向函數(shù),函數(shù)返回值是指針類型。

結(jié)構(gòu)體
- 產(chǎn)生的意義
- 類型描述
- 嵌套定義
- 定義變量、初始化及引用
- 占用內(nèi)存大小
定義和使用:
#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;
}內(nèi)存對齊問題
addr/sizeof()
構(gòu)造類型-結(jié)構(gòu)體內(nèi)存問題及函數(shù)傳參

為后面linux高級鋪墊。
- 可以實(shí)現(xiàn)一個(gè)學(xué)生管理系統(tǒng)。
- 產(chǎn)生及意義
- 類型描述
- 嵌套定義
- 定義變量
- 占用內(nèi)存大小
- 函數(shù)傳參
- 位域
union 名{
數(shù)據(jù)類型 成員名1;
數(shù)據(jù)類型 成員名2;
};枚舉類型
enum 名{
成員1;
成員2;
成員3;
}到此這篇關(guān)于C/C++指針、函數(shù)、結(jié)構(gòu)體、共用體的文章就介紹到這了,更多相關(guān)C++指針 函數(shù) 結(jié)構(gòu)體 共用體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)字符轉(zhuǎn)unix時(shí)間戳的簡單實(shí)例
下面小編就為大家?guī)硪黄狢語言實(shí)現(xiàn)字符轉(zhuǎn)unix時(shí)間戳的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-06-06
C++實(shí)現(xiàn)中綴轉(zhuǎn)后綴的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)中綴轉(zhuǎn)后綴的問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
C語言實(shí)現(xiàn)倉庫物資管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)倉庫物資管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
C++調(diào)用libcurl開源庫實(shí)現(xiàn)郵件的發(fā)送功能流程詳解
libcurl是一個(gè)免費(fèi)開源的網(wǎng)絡(luò)傳輸庫,支持ftp、ftps、tftp,http、https、telnet、ldap、pop3、smtp等多種協(xié)議,接下來讓我們一起來了解吧2021-11-11
C++實(shí)現(xiàn)LeetCode(62.不同的路徑)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(62.不同的路徑),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

