uc_day02
一,C語言中的錯誤處理
1,錯誤處理方式
error.c
#include<stdio.h>
max(int x, int y){
return x > y?x:y;
}
int main(){
int r = max(3,4);
printf("r=%d\n",r);
return 0;
}
要求:返回最大值,如果相等,返回錯誤信息
#include<stdio.h>
max(int x, int y,int* r){
if(x == y) return -1;
*r = x>y?x:y;
return 0;
}
int main(){
int r;
if(max(3,4,&r) == -1){
printf("函數調用錯誤\n");
return -1;
}
printf("r=%d\n",r);
return 0;
}
出錯指針返回NULL,整數返回-1
C語言中如果返回值是void,有一個潛藏的含義,這個函數調用不會出錯
輸出參數的常用方法
2,錯誤處理
errno.c
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main(){
FILE* file = fopen("etc/passwd","r");
if(file == NULL){
printf("錯誤原因:%d\n",errno);
printf("錯誤原因:%s\n",strerror(errno));
printf("ERROR:%m\n");
perror("錯誤");
return -1;
}
printf("文件打開成功\n");
return 0;
}
-------------------------------------------------
FILE* file2 = fopen("etc/passwd","w");
if(errno != 0){
perror("打開文件失敗");
}
//不能用errno的值判斷剛纔的操作是否出錯,只能是當有錯誤發生時,
用errno來獲取錯誤的原因
二,環境表
env 是shell所擁有的環境變量,在內存中
env.c//程序中獲取這個環境表
#include<stdio.h>
#include<string.h>
int main(){
extern char** environ;//聲明全局變量
printf("environ=%p\n",viron);
char** p = envirson;
while(*p){
printf("%s\n",*p);
p++;
}
char value[100] = {};//將環境變量LANG的值保存在value中
p = envirson;
while(*p){
//拿一個環境變量,看看是否是LANG,如果是,將=號後面的值保存到value中
if(strncmp(*p,"LANG")==0){
strcpy(value,*p+5);
break;
}
p++;
}
printf("value=%s\n",value);
printf("===================\n");
return 0;
}
這張環境表是一個char** environ[]類型的數組
最後的元素是一個NULL
------------------------------------------------
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char** argv, char** env){
extern char** environ;
printf("environ=%p\n",environ);
printf("env=%p\n",env);
char* value = getenv("LANG");
putenv("VAR=abc");
putenv("LANG=c");//修改或添加環境添加。不存在,添加,存在,修改
printf("value=%s\n",value);
return 0;
}
三,內存管理
1,STL ==> 內存自動的分配和釋放
2,定位分配---C++
char buf[1024] = {};
int* p2 = new (buf)int;
*p2 = 200;
cout << *(int*)buf <<endl;
cout << *p2 << endl;
p2分配到了棧空間了 分配到了buf裏面了
定位分配可以在棧空間,也可以在全局空間
不能再代碼區分配空間
只有在堆空間分配需要delete
C++中的new/delete會調用構造和析構函數
3,C++ new/delete 會調用malloc和free
new.cpp
#include<iostream>
using namespace std;
class Sample{
int x;
Sample(){cout << "Sample()" << endl;}
~Sample(){cout << "~Sample()" << endl;}
void show(){cout <<"x=" << x << endl;}
};
int main(){
Sample* s = new Sample;
s->x = 100;
s->show();
delete s;
Sample* s2 = (Sample*)malloc(sizeof(Sample));
s2->x = 200;
s2->show();
free(s2);
Sample* s3 = new Sample[5];//構造和析構調用五次
delete[] s3;
Sample s5[5];//會構造五個對象出來,是在棧裏面的分配的
//棧中是自動的分配和釋放
return 0;
}
4,C語言中是malloc和free
5,unix規範 sbrk/brk
6,Linux分配 mmap
7,系統調用(內核) kmalloc vmalloc
get_free_page() 獲取空閒的內存頁面
四,進程空間
1,程序:在磁盤上保存的可以運行的文件
開始從PATH找,找到後讀取到內存中
2,進程:正在運行的程序,存在內存中
memory.c
#include<stdio.h>
int main(){
int x = 100;
printf("x=%d\n",x);
return 0;
}
執行a.out的時候,先按照PATH從磁盤上找,找到後讀到內存
代碼讀取到內存中存放的位置叫代碼區(code)
代碼區(code)
全局區
BSS段
棧區(stack)
堆區(heap)
3,一個進程空間被劃分爲一下部分:
1)代碼區:要執行的程序被放入此區,只讀區域
從08048000開始
2)全局區:保存全局變量,全局變量在main函數執行之前分配
3)BSS段:保存未初始化的全局變量,BSS段在main函數執行之前會被
清零。全局區和BSS段可稱爲全局區,靜態區,數據區等
全局變量未被初始化是0,局部是垃圾數據,隨機的
4)棧區:保存局部變量(包括函數參數),內存分配和釋放自動進行的
棧中的變量也稱爲自動變量
5)堆區:也叫自由區,分配new,malloc分配出來的內存空間。
空間的分配和釋放由程序員決定的。
ps -ef | grep a.out
cd /proc/4778
全局初始化的在全局區
全局未賦值的在BSS
全局常量在代碼區
函數參數和局部變量在棧區
靜態局部變量在全局區
局部常量在棧區
局部整形指針在堆區
局部字符指針在代碼區
局部字符數組在棧中
char.c
#include<stdio.h>
#include<string.h>
int main(){
char* str1 = "abcdef";//str1四個字節,在棧裏面,保存的內容在代碼區中
str1[0] = 'A';//段錯誤,代碼區是隻讀區域,不能更改的
printf("str1=%p\n",str1);
str1 = "ABCDEF";//正確,改變的是str1的值,改變的是棧,而不是代碼區
char str2[] = "abcdef";
str2[0] = 'A';
return 0;
}
%s後面要的是地址
=======================================================
????????????????????
char* str1="abcdef";
printf("str1=%c\n",*str1);
=========================================================
stack.c
#include<stdio.h>
#include<string.h>
void fa(){
int x;//自動變量,在棧中分配的4Byes的空間
x = 100;
x = "abc";
printf("x=%s\n",x);
strcpy(&x,"abc");//正確
strcpy(&x,"abcdef");//錯誤
printf("x=%x\n",x);
printf("&x=%s\n",&x);
}
int main(){
fa();
return 0;
}
注:代碼區只讀,不能改
棧區的數據很特別,內存,存數據,類型,const等等僅僅是讓編譯器看的
1,錯誤處理方式
error.c
#include<stdio.h>
max(int x, int y){
return x > y?x:y;
}
int main(){
int r = max(3,4);
printf("r=%d\n",r);
return 0;
}
要求:返回最大值,如果相等,返回錯誤信息
#include<stdio.h>
max(int x, int y,int* r){
if(x == y) return -1;
*r = x>y?x:y;
return 0;
}
int main(){
int r;
if(max(3,4,&r) == -1){
printf("函數調用錯誤\n");
return -1;
}
printf("r=%d\n",r);
return 0;
}
出錯指針返回NULL,整數返回-1
C語言中如果返回值是void,有一個潛藏的含義,這個函數調用不會出錯
輸出參數的常用方法
2,錯誤處理
errno.c
#include<stdio.h>
#include<errno.h>
#include<string.h>
int main(){
FILE* file = fopen("etc/passwd","r");
if(file == NULL){
printf("錯誤原因:%d\n",errno);
printf("錯誤原因:%s\n",strerror(errno));
printf("ERROR:%m\n");
perror("錯誤");
return -1;
}
printf("文件打開成功\n");
return 0;
}
-------------------------------------------------
FILE* file2 = fopen("etc/passwd","w");
if(errno != 0){
perror("打開文件失敗");
}
//不能用errno的值判斷剛纔的操作是否出錯,只能是當有錯誤發生時,
用errno來獲取錯誤的原因
二,環境表
env 是shell所擁有的環境變量,在內存中
env.c//程序中獲取這個環境表
#include<stdio.h>
#include<string.h>
int main(){
extern char** environ;//聲明全局變量
printf("environ=%p\n",viron);
char** p = envirson;
while(*p){
printf("%s\n",*p);
p++;
}
char value[100] = {};//將環境變量LANG的值保存在value中
p = envirson;
while(*p){
//拿一個環境變量,看看是否是LANG,如果是,將=號後面的值保存到value中
if(strncmp(*p,"LANG")==0){
strcpy(value,*p+5);
break;
}
p++;
}
printf("value=%s\n",value);
printf("===================\n");
return 0;
}
這張環境表是一個char** environ[]類型的數組
最後的元素是一個NULL
------------------------------------------------
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char** argv, char** env){
extern char** environ;
printf("environ=%p\n",environ);
printf("env=%p\n",env);
char* value = getenv("LANG");
putenv("VAR=abc");
putenv("LANG=c");//修改或添加環境添加。不存在,添加,存在,修改
printf("value=%s\n",value);
return 0;
}
三,內存管理
1,STL ==> 內存自動的分配和釋放
2,定位分配---C++
char buf[1024] = {};
int* p2 = new (buf)int;
*p2 = 200;
cout << *(int*)buf <<endl;
cout << *p2 << endl;
p2分配到了棧空間了 分配到了buf裏面了
定位分配可以在棧空間,也可以在全局空間
不能再代碼區分配空間
只有在堆空間分配需要delete
C++中的new/delete會調用構造和析構函數
3,C++ new/delete 會調用malloc和free
new.cpp
#include<iostream>
using namespace std;
class Sample{
int x;
Sample(){cout << "Sample()" << endl;}
~Sample(){cout << "~Sample()" << endl;}
void show(){cout <<"x=" << x << endl;}
};
int main(){
Sample* s = new Sample;
s->x = 100;
s->show();
delete s;
Sample* s2 = (Sample*)malloc(sizeof(Sample));
s2->x = 200;
s2->show();
free(s2);
Sample* s3 = new Sample[5];//構造和析構調用五次
delete[] s3;
Sample s5[5];//會構造五個對象出來,是在棧裏面的分配的
//棧中是自動的分配和釋放
return 0;
}
4,C語言中是malloc和free
5,unix規範 sbrk/brk
6,Linux分配 mmap
7,系統調用(內核) kmalloc vmalloc
get_free_page() 獲取空閒的內存頁面
四,進程空間
1,程序:在磁盤上保存的可以運行的文件
開始從PATH找,找到後讀取到內存中
2,進程:正在運行的程序,存在內存中
memory.c
#include<stdio.h>
int main(){
int x = 100;
printf("x=%d\n",x);
return 0;
}
執行a.out的時候,先按照PATH從磁盤上找,找到後讀到內存
代碼讀取到內存中存放的位置叫代碼區(code)
代碼區(code)
全局區
BSS段
棧區(stack)
堆區(heap)
3,一個進程空間被劃分爲一下部分:
1)代碼區:要執行的程序被放入此區,只讀區域
從08048000開始
2)全局區:保存全局變量,全局變量在main函數執行之前分配
3)BSS段:保存未初始化的全局變量,BSS段在main函數執行之前會被
清零。全局區和BSS段可稱爲全局區,靜態區,數據區等
全局變量未被初始化是0,局部是垃圾數據,隨機的
4)棧區:保存局部變量(包括函數參數),內存分配和釋放自動進行的
棧中的變量也稱爲自動變量
5)堆區:也叫自由區,分配new,malloc分配出來的內存空間。
空間的分配和釋放由程序員決定的。
ps -ef | grep a.out
cd /proc/4778
全局初始化的在全局區
全局未賦值的在BSS
全局常量在代碼區
函數參數和局部變量在棧區
靜態局部變量在全局區
局部常量在棧區
局部整形指針在堆區
局部字符指針在代碼區
局部字符數組在棧中
char.c
#include<stdio.h>
#include<string.h>
int main(){
char* str1 = "abcdef";//str1四個字節,在棧裏面,保存的內容在代碼區中
str1[0] = 'A';//段錯誤,代碼區是隻讀區域,不能更改的
printf("str1=%p\n",str1);
str1 = "ABCDEF";//正確,改變的是str1的值,改變的是棧,而不是代碼區
char str2[] = "abcdef";
str2[0] = 'A';
return 0;
}
%s後面要的是地址
=======================================================
????????????????????
char* str1="abcdef";
printf("str1=%c\n",*str1);
=========================================================
stack.c
#include<stdio.h>
#include<string.h>
void fa(){
int x;//自動變量,在棧中分配的4Byes的空間
x = 100;
x = "abc";
printf("x=%s\n",x);
strcpy(&x,"abc");//正確
strcpy(&x,"abcdef");//錯誤
printf("x=%x\n",x);
printf("&x=%s\n",&x);
}
int main(){
fa();
return 0;
}
注:代碼區只讀,不能改
棧區的數據很特別,內存,存數據,類型,const等等僅僅是讓編譯器看的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.