详解R语言中的PCA分析与可视化

1. 常用术语

(1)标准化(Scale)

如果不对数据进行scale处理,本身数值大的基因对主成分的贡献会大。如果关注的是变量的相对大小对样品分类的贡献,则应SCALE,以防数值高的变量导入的大方差引入的偏见。但是定标(scale)可能会有一些负面效果,因为定标后变量之间的权重就是变得相同。如果我们的变量中有噪音的话,我们就在无形中把噪音和信息的权重变得相同,但PCA本身无法区分信号和噪音。在这样的情形下,我们就不必做定标。

(2)特征值 (eigen value)

特征值与特征向量均为矩阵分解的结果。特征值表示标量部分,一般为某个主成分的方差,其相对比例可理解为方差解释度或贡献度 ;特征值从第一主成分会逐渐减小。

(3)特征向量(eigen vector)

特征向量为对应主成分的线性转换向量(线性回归系数),特征向量与原始矩阵的矩阵积为主成分得分。特征向量是单位向量,其平方和为1。特征向量主要起转换作用,其数值不能说明什么问题,解释力更强的是载荷loadings,但很多R输出中经常混用,engen vector与loadings。

(4)载荷(loading)

因子载荷矩阵并不是主成分的特征向量,即不是主成分的系数。主成分系数的求法:各自因子载荷向量除以各自因子特征值的算数平方根。

  • 特征向量是单位向量,特征向量乘以特征值的平方根构造了载荷loading。
  • 列上看,不同变量对某一PC的loadings的平方和等于其征值,因此每个变量的loadings值可表征其对PC的贡献。
  • 行上看,同一变量对不同PCs的loadings行平方和为1,表征不同PCs对某一变量方差的解释度。

(5)得分(score)

指主成分得分,矩阵与特征向量的积。·

2. PCA分析过程

2.0 手动计算

#特征分解
dat_eigen<-scale(iris[,-5],scale=T)%>%cor()%>%eigen()
#特征值提取
dat_eigen$values
#特征向量提取
dat_eigen$vectors
#求loadings=eigen vector*sqrt(eigen value),与princomp不同
#主成分载荷表示各个主成分与原始变量的相关系数。
sweep(dat_eigen$vectors,2,sqrt(dat_eigen$values),"*")
#将中心化的变量矩阵得到每个观测值的得分
scale(iris[,-5],scale=T)%*%dat_eigen$vectors%>%head() 

2.1 prcomp函数

prcomp函数使用较为简单,但是不同于常规的求取特征值和特征向量的方法,prcomp函数是对变量矩阵(相关矩阵)采用SVD方法计算其奇异值(原理上是特征值的平方根),函数帮助中描述为函数结果中的sdev。
prcomp函数输入参数为变量矩阵(x),中心化(center,默认为true),标准化(scale,默认为false,建议改为true),主成份个数(rank)。
prcomp函数输出有sdev(各主成份的奇异值),rotation(特征向量,回归系数),x(score得分矩阵)。

iris.pca<-prcomp(iris[,-5],scale=T,rank=4,retx=T) #相关矩阵分解
	#retx表四返回score,scale表示要标准化
	summary(iris.pca) #方差解释度
	iris.pca$sdev #特征值的开方
	iris.pca$rotation #特征向量,回归系数
	iris.pca$x #样本得分score

2.2 princomp函数

princomp以计算相关矩阵或者协方差矩阵的特征值为主要手段。
princomp函数输出有主成份的sd,loading,score,center,scale.
prcomp函数使用较为简单,但是不同于常规的求取特征值和特征向量的方法,prcomp函数是对变量矩阵(相关矩阵)采用SVD方法计算其奇异值(原理上是特征值的平方根),函数帮助中描述为函数结果中的sdev。
prcomp函数输入参数为变量矩阵(x),中心化(center,默认为true),标准化(scale,默认为false,建议改为true),主成份个数(rank)。
prcomp函数输出有sdev(各主成份的奇异值及其方差累积),rotation(载荷矩阵),x(得分矩阵),center(变量的均值),scale(变量的标准偏差)

data(wine) #三种葡萄酿造的红酒品质分析数据集
wine.pca<-princomp(wine,cor=T,scores=T)
#默认方差矩阵(cor=F),改为cor=T则结果与prcomp相同
summary(wine.pca) #各主成份的SVD值以及相对方差
wine.pca$loading #特征向量,回归系数
wine.pca$score
screenplot(wine.pca) #方差分布图
biplot(wine.pca,scale=F) #碎石图,直接把x与rotation绘图,而不标准化

2.3 psych::principal

实际上该principal主要用于因子分析。

model_pca<-psych::principal(iris[,-5],nfactors=4,rotate="none")
model_pca$values # 特征值=sdev^2
# 此处loadings与手动计算相同=prcomp的rotation*sdev
model_pca%>%.$loadings #载荷,不是特征向量
#此处score=prcomp的score/sdev
model_pca$scores[1:5,] #此处为因子得分,不是主成分得分
model_pca$weights #此处为上面loadings/特征值,也称成份得分系数或者因子系数

3. PCA结果解释

下文引用chentong的内容

prcomp函数会返回主成分的标准差、特征向量和主成分构成的新矩阵。
不同主成分对数据差异的贡献和主成分与原始变量的关系。
1. 主成分的平方为为特征值,其含义为每个主成分可以解释的数据差异,计算方式为 eigenvalues = (pca$sdev)^2
2. 每个主成分可以解释的数据差异的比例为 percent_var = eigenvalues*100/sum(eigenvalues)
3. 可以使用summary(pca)获取以上两条信息。

这两个信息可以判断主成分分析的质量:
 成功的降维需要保证在前几个为数不多的主成分对数据差异的解释可以达到80-90%。

指导选择主成分的数目:
 1. 选择的主成分足以解释的总方差大于80% (方差比例碎石图)
 2. 从前面的协方差矩阵可以看到,自动定标(scale)的变量的方差为1 (协方差矩阵对角线的值)。待选择的主成分应该是那些方差大于1的主成分,即其解释的方差大于原始变量(特征值碎石图,方差大于1,特征值也会大于1,反之亦然)。

鉴定核心变量和变量间的隐性关系:
 原始变量与主成分的相关性 Variable correlation with PCs (var.cor) = loadings * sdev
 原始数据对主成分的贡献度 var.cor^2 / (total var.cor^2)

4. PCA结果可视化

4.1 ggbiplot包

devtools::install_github("vqv/ggbiplot")
library(ggbiplot)
ggscreeplot(wine.pca) #碎石图

碎石图

biplot

ggbiplot(wine.pca, obs.scale = 1, var.scale = 1,
   groups = wine.class, ellipse = TRUE, circle = TRUE) +
 scale_color_discrete(name = '') +
 theme(legend.direction = 'horizontal', legend.position = 'top')

4.2 ggfortify包

ggfortify包中autoplot函数可自动绘制。

library(ggfortify)
pca1<-iris%>%select(-5)%>%prcomp()
autoplot(pca1,data = iris,col= 'Species',size=2,
   loadings =T,loadings.label = TRUE,
   frame = TRUE,frame.type='norm',
   label = TRUE, label.size = 3
)+ theme_classic()

4.3 factoextra包可视化

FactoMineR与factoextra分别进行PCA分析与可视化,当然factoextra包中函数也可对prcomp、princomp函数结果进行可视化。

library(factoextra)
library(FactoMineR)
# 利用FactoMineR包中PCA函数进行PCA分析
> wine.pca2 <- PCA(wine,scale.unit = T,ncp=5,graph = T) #

wine.pca2中内容

> print(wine.pca2)
**Results for the Principal Component Analysis (PCA)**
The analysis was performed on 178 individuals, described by 13 variables
*The results are available in the following objects:

 name    description
1 "$eig"    "eigenvalues"
2 "$var"    "results for the variables"
3 "$var$coord"  "coord. for the variables"
4 "$var$cor"   "correlations variables - dimensions"
5 "$var$cos2"  "cos2 for the variables"
6 "$var$contrib"  "contributions of the variables"
7 "$ind"    "results for the individuals"
8 "$ind$coord"  "coord. for the individuals"
9 "$ind$cos2"  "cos2 for the individuals"
10 "$ind$contrib"  "contributions of the individuals"
11 "$call"   "summary statistics"
12 "$call$centre"  "mean of the variables"
13 "$call$ecart.type" "standard error of the variables"
14 "$call$row.w"  "weights for the individuals"
15 "$call$col.w"  "weights for the variables"

摘要信息

> summary(wine.pca2)

Call:
PCA(X = wine, scale.unit = T, ncp = 5, graph = T) 

Eigenvalues
      Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6 Dim.7 Dim.8 Dim.9 Dim.10
Variance    4.706 2.497 1.446 0.919 0.853 0.642 0.551 0.348 0.289 0.251
% of var.    36.199 19.207 11.124 7.069 6.563 4.936 4.239 2.681 2.222 1.930
Cumulative % of var. 36.199 55.406 66.530 73.599 80.162 85.098 89.337 92.018 94.240 96.170
      Dim.11 Dim.12 Dim.13
Variance    0.226 0.169 0.103
% of var.    1.737 1.298 0.795
Cumulative % of var. 97.907 99.205 100.000

...省略...

还输出了简易的图

4.3.1 特征值可视化 提取特征值

> get_eigenvalue(wine.pca2) #标准化数据中特征值>1的变量解释能力较强
  eigenvalue variance.percent cumulative.variance.percent
Dim.1 4.7058503  36.1988481     36.19885
Dim.2 2.4969737  19.2074903     55.40634
Dim.3 1.4460720  11.1236305     66.52997
...省略部分

碎石图

fviz_eig(wine.pca2,addlabels = TRUE) #碎石图,展示方差解释度

4.3.2 变量信息可视化

变量提取主要有get_pca_var()函数,输出变量在主成分投影上的坐标,变量与主成分PC的相关系数,相关系数的平方,变量对某一PC的相关贡献

#get_pca_var()等同于get_pca(element="var")
> get_pca_var(wine.pca2)#coord cor cos2 contribution
Principal Component Analysis Results for variables
 ===================================================
 Name  Description
1 "$coord" "Coordinates for the variables"
2 "$cor"  "Correlations between variables and dimensions"
3 "$cos2" "Cos2 for the variables"
4 "$contrib" "contributions of the variables"
> wine.pca2$var #输出上述数据
> get_pca_var(wine.pca2)$coord
> get_pca_var(wine.pca2)$cos2

变量坐标(coord)与相关性(cor)可视化

coord是坐标(实际的loading),与cor数值相同
coord=eigen vector * stdev
相关图中,靠近的变量表示正相关;对向的是负相关。
箭头越远离远原点、越靠经圆圈表明PC对其的代表性高(相关性强)

fviz_pca_var(wine.pca2) #变量相关性可视化图

cos2可视化

cos2代表不同主成分对变量的代表性强弱,对特定变量,所有组成份上的cos2之和为1,因为cos2为cor的平方,所以也认为是相关性越强,其结果与cor类似。

#cos2是coord的平方,表征特定变量在所有PC上的代表性,某个变量的所有cos2总和为1
library("corrplot")
corrplot(get_pca_var(wine.pca2)$cos2, is.corr=FALSE)

下图中PC1对Phenols变量的代表性最好

fviz_cos2(wine.pca2, choice = "var", axes = 1:2)
# cos2在主成分上的加和,并排序

#不同按照cos2大小设定颜色梯度,也可以设置alpha梯度
fviz_pca_var(wine.pca2,axes=c(1,2),
 col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
    repel = TRUE) # Avoid text overlapping

contrib可视化

contrib是每个变量对某一特定PC的贡献
contrib=(var.cos2 * 100) / (total cos2 of the PC component)
多个变量的contrib = [(Contrb1 * Eig1) + (Contrib2 * Eig2)]/(Eig1 + Eig2)

> get_pca_var(wine.pca2)$contrib
      Dim.1  Dim.2  Dim.3  Dim.4  Dim.5
Alcohol  2.083097e+00 23.391881971 4.3007553 0.03188475 7.0577176
MalicAcid  6.011695e+00 5.059392535 0.7923294 28.82511766 0.1240000
Ash   4.206853e-04 9.989949520 39.2156374 4.58711714 2.0456286
AlcAsh   5.727426e+00 0.011215874 37.4642355 0.37038683 0.4369599
Mg    2.016174e+00 8.978053590 1.7097376 12.37608338 52.8599543
Phenols  1.557572e+01 0.423013810 2.1368289 3.92310704 2.2295987
Flav   1.788734e+01 0.001128834 2.2705035 2.31937045 1.1886633
NonFlavPhenols 8.912201e+00 0.082825894 2.9025311 4.13313047 25.0703477
Proa   9.823804e+00 0.154462537 2.2336591 15.92461164 1.8730611
Color   7.852920e-01 28.089541241 1.8852996 0.43461955 0.5842581
Hue   8.803953e+00 7.797226784 0.7262776 18.29883787 3.0142002
OD    1.415019e+01 2.705899746 2.7557523 3.39004479 1.0233546
Proline  8.222684e+00 13.315407665 1.6064528 5.38568842 2.4922558
fviz_contrib(wine.pca2, choice = "var", axes = 1:2)
corrplot(get_pca_var(wine.pca2)$contrib, is.corr=FALSE) 

fviz_contrib(wine.pca2, choice = "var", axes = 1:2)

根据contribution将变量颜色分类

fviz_pca_var(wine.pca2,col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"))

变量分组

#人为分组
bb<-as.factor(c(rep(c("soil","micro","plant"),4),"soil"))
names(bb)<-row.names(wine.pca2$var$contrib)
fviz_pca_var(wine.pca2, col.var = bb, palette = c("#0073C2FF", "#EFC000FF", "#868686FF"),
    legend.title = "Cluster")

4.3.3 样本可视化scores 样本坐标可视化

get_pca_ind(wine.pca2) #coord cor cos2 contribution
get_pca(element="ind)

get_pca_ind(wine.pca2) #coord cor cos2 contribution
wine.pca2$ind #coord cos2 contrib dist
fviz_pca_ind(wine.pca2)#score 可视化coord

fviz_pca_ind(wine.pca2, geom=c("point","text"),
   addEllipses = T,
   pointshape=21,col.ind="black",pointsize="cos2",
   fill.ind = wine.class,palette = "npg",
   #col.ind="cos2", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
   #col.ind="contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
   # label=wine.class,
   repel = TRUE)

fviz_pca_ind(wine.pca2, axes = c(1, 2),label="none", #habillage只能是分类变量
    addEllipses = TRUE, ellipse.type="norm",ellipse.level=0.9,
    # one of "confidence","t","norm","euclid","convex"
    habillage = wine.class,palette = "jco",
    mean.point=F
    )

样本的cos2与contrib图

fviz_cos2(wine.pca2, choice = "ind",axes=1:2)

fviz_contrib(wine.pca2, choice = "ind", axes = 1:2)

4.3.4 biplot

biplot不需要关注具体数值,只需要关注方向与位置
样本在变量同侧是具有高数值,反之则值低

fviz_pca_biplot(wine.pca2, axes = c(1,2),repel = F,
    addEllipses = T,ellipse.alpha=0.15,
    geom=c("point"),geom.var=c("arrow","text"),
    arrowsize=1.5,labelsize=5, #arrow与text大小
    pointshape=21,pointsize=5,fill.ind = wine.class,col.ind="black", #point
    col.var=factor(c(rep(c("soil","plant"),6),"plant"))

)%>%ggpar(xlab="PC1",ylab="PC2",title="PCA-Biplot",
   font.x=14,font.y=14,font.tickslab = 14,ggtheme=theme_bw(),ylim=c(-4.5,4.5),
   legend.title = list(color="Variable",fill="Class"),font.legend = 12,
   )+
  ggpubr::fill_palette("jco")+ggpubr::color_palette("npg")+
 theme(axis.ticks.length= unit(-0.25, 'cm'), #设置y轴的刻度长度为负数,即向内
  axis.text.y.left = element_text(margin = unit(c(0.5, 0.5, 0.5, 0.05), 'cm')),
  axis.text.x.bottom = element_text(margin = unit(c(0.5, 0.5, 0.05, 0.5), 'cm'))
  )

到此这篇关于详解R语言中的PCA分析与可视化的文章就介绍到这了,更多相关R语言PCA分析与可视化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • R语言利用loess如何去除某个变量对数据的影响详解

    R语言介绍 R语言是用于统计分析,图形表示和报告的编程语言和软件环境. R语言由Ross Ihaka和Robert Gentleman在新西兰奥克兰大学创建,目前由R语言开发核心团队开发. R语言的核心是解释计算机语言,其允许分支和循环以及使用函数的模块化编程. R语言允许与以C,C ++,.Net,Python或FORTRAN语言编写的过程集成以提高效率. R语言在GNU通用公共许可证下免费提供,并为各种操作系统(如Linux,Windows和Mac)提供预编译的二进制版本. R是一个在GNU

  • R语言 vs Python对比:数据分析哪家强?

    什么是R语言? R语言,一种自由软件编程语言与操作环境,主要用于统计分析.绘图.数据挖掘.R本来是由来自新西兰奥克兰大学的罗斯·伊哈卡和罗伯特·杰特曼开发(也因此称为R),现在由"R开发核心团队"负责开发.R基于S语言的一个GNU计划项目,所以也可以当作S语言的一种实现,通常用S语言编写的代码都可以不作修改的在R环境下运行.R的语法是来自Scheme. R的源代码可自由下载使用,亦有已编译的可执行文件版本可以下载,可在多种平台下运行,包括UNIX(也包括FreeBSD和Linux).W

  • 详解R语言中的多项式回归、局部回归、核平滑和平滑样条回归模型

    在标准线性模型中,我们假设 .当线性假设无法满足时,可以考虑使用其他方法. 多项式回归 扩展可能是假设某些多项式函数, 同样,在标准线性模型方法(使用GLM的条件正态分布)中,参数  可以使用最小二乘法获得,其中  在  . 即使此多项式模型不是真正的多项式模型,也可能仍然是一个很好的近似值 .实际上,根据 Stone-Weierstrass定理,如果  在某个区间上是连续的,则有一个统一的近似值  ,通过多项式函数. 仅作说明,请考虑以下数据集 db = data.frame(x=xr,y=y

  • R语言dplyr包之高效数据处理函数(filter、group_by、mutate、summarise)详解

    R语言dplyr包的数据整理.分析函数用法文章连载NO.01 在日常数据处理过程中难免会遇到些难处理的,选取更适合的函数分割.筛选.合并等实在是大快人心! 利用dplyr包中的函数更高效的数据清洗.数据分析,及为后续数据建模创造环境:本篇涉及到的函数为filter.filter_all().filter_if().filter_at().mutate.group_by.select.summarise. 1.数据筛选函数: #可使用filter()函数筛选/查找特定条件的行或者样本 #filte

  • 详解R语言中生存分析模型与时间依赖性ROC曲线可视化

    R语言简介 R是用于统计分析.绘图的语言和操作环境.R是属于GNU系统的一个自由.免费.源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具. 人们通常使用接收者操作特征曲线(ROC)进行二元结果逻辑回归.但是,流行病学研究中感兴趣的结果通常是事件发生时间.使用随时间变化的时间依赖性ROC可以更全面地描述这种情况下的预测模型. 时间依赖性ROC定义 令 Mi为用于死亡率预测的基线(时间0)标量标记. 当随时间推移观察到结果时,其预测性能取决于评估时间 t.直观地说,在零时间测量的标记值应该

  • 详解R语言中的PCA分析与可视化

    1. 常用术语 (1)标准化(Scale) 如果不对数据进行scale处理,本身数值大的基因对主成分的贡献会大.如果关注的是变量的相对大小对样品分类的贡献,则应SCALE,以防数值高的变量导入的大方差引入的偏见.但是定标(scale)可能会有一些负面效果,因为定标后变量之间的权重就是变得相同.如果我们的变量中有噪音的话,我们就在无形中把噪音和信息的权重变得相同,但PCA本身无法区分信号和噪音.在这样的情形下,我们就不必做定标. (2)特征值 (eigen value) 特征值与特征向量均为矩阵分

  • 详解go语言中sort如何排序

    目录 sort包源码解读 前言 如何使用 基本数据类型切片的排序 自定义Less排序比较器 自定义数据结构的排序 分析下源码 不稳定排序 稳定排序 查找 Interface 总结 参考 sort 包源码解读 前言 我们的代码业务中很多地方需要我们自己进行排序操作,go 标准库中是提供了 sort 包是实现排序功能的,这里来看下生产级别的排序功能是如何实现的. go version go1.16.13 darwin/amd64 如何使用 先来看下 sort 提供的主要功能 对基本数据类型切片的排序

  • 详解 Go 语言中 Map 类型和 Slice 类型的传递

    Map 类型 先看例子 m1: func main() { m := make(map[int]int) mdMap(m) fmt.Println(m) } func mdMap(m map[int]int) { m[1] = 100 m[2] = 200 } 结果是 map[2:200 1:100] 我们再修改如下 m2: func main() { var m map[int]int mdMap(m) fmt.Println(m) } func mdMap(m map[int]int) {

  • 详解C++语言中std::array的神奇用法

    概述 std::array是在C++11标准中增加的STL容器,它的设计目的是提供与原生数组类似的功能与性能.也正因此,使得std::array有很多与其他容器不同的特殊之处,比如:std::array的元素是直接存放在实例内部,而不是在堆上分配空间:std::array的大小必须在编译期确定:std::array的构造函数.析构函数和赋值操作符都是编译器隐式声明的--这让很多用惯了std::vector这类容器的程序员不习惯,觉得std::array不好用.但实际上,std::array的威力

  • 详解C语言中return返回函数局部变量的问题

    目录 return返回栈区局部变量的指针 return返回栈区局部的临时变量 return只读数据段和static数据 在计算机中,释放空间并不需要将空间中的内容全部置成0或者1,而是只要设置这一块空间的数据无效即可.比如在下载文件时需要花很长时间,但是删除文件却只要几秒钟,这是因为操作系统只是把文件标识(文件头链接)删掉了,文件原文还保留着,我们没了文件标识就找不到这个文件了.所以删除后的文件,还可以用特殊的办法被找回来. 这也就意味着,当函数结束调用的时候,函数中的局部变量实际上还是在的,只

  • 详解C语言中typedef和#define的用法与区别

    目录 一.typedef的用法 二.#define的用法 三.typedef与#define的区别 四.typedef的用途 用途一 用途二 用途三 用途四 五.typedef的陷阱 陷阱一 陷阱二 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,比如: typedef int INT; typedef (int*) pINT; typedef unsigned int uint32_t type

  • 详解Go语言中rand(随机数)包的使用

    目录 包"math/rand" 随机数种子 随机函数 rand.Int() rand.Intn(n) 实例 其他随机函数 按类型随机类 指定随机范围类 伪随机排列的切片 生成标准正态分布 生成标准指数分布 包"math/rand" 随机数生成器,可以生成 整型或浮点型 的伪随机数. 随机数种子 不同的种子生成不同的随机数,无种子编译后运行的结果是定值. 通常以时钟作为参数初始化,rand.Seed(time.Now().UnixNano()). 随机函数 rand.

  • 详解Go语言中new和make关键字的区别

    目录 new 源码 使用 make 源码 使用 总结 本篇文章来介绍一道非常常见的面试题,到底有多常见呢?可能很多面试的开场白就是由此开始的.那就是 new 和 make 这两个内置函数的区别. 其实这个问题本身并不复杂,简单来说就是,new 只分配内存,而 make 只能用于 slice.map 和 chan 的初始化,下面我们就来详细介绍一下. new new 是一个内置函数,它会分配一段内存,并返回指向该内存的指针. 其函数签名如下: 源码 // The new built-in func

  • 详解C语言中return与exit的区别

    详解C语言中return与exit的区别 1,exit用于在程序运行的过程中随时结束程序,exit的参数是返回给OS的.main函数结束时也会隐式地调用exit函数.exit函数运行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同时刷新所有输出流.关闭所有打开的流并且关闭通过标准I/O函数tmpfile()创建的临时文件.exit是结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程,而return是返回函数值并退出函数 2,return是语言级别的,它

  • 详解C语言中Char型指针数组与字符数组的区别

    详解C语言中Char型指针数组与字符数组的区别 1.char 类型的指针数组:每个元素都指向一个字符串,指向可以改变 char *name[3] = { "abc", "def", "gbk" }; for(int i = 0 ; i < strlen(name); i ++){ printf("%s\n", *(name+i)); //printf("%s\n", name[i]); } //指向改

随机推荐