C語言基礎
字符串
- 字符串:由多個字符構成,最后一個字符必須要是'\0'
- 字符數組:由多個字符構成
- 表達方式
- char str[10]={'a','b','c'};
- char str[10]={"hello"};
- char str[10]="hello";
char str[10]="hello"; str[2]='m';
- hello存放在文字常量區,但是str扯個字符串存在棧區,度文字常量區的內容進行了拷貝,所以可修改str里的字符創里的變量。
- char *p="hello";
- 用p[2]='m'會出錯,因為文字常量區常量字符串只讀不可更改
char *p="hello"; char *q="hello"; printf("p=%p,q=%p",p,q)//結果相同
char *p="hello" printf("%c\n",*(p++));//h printf("%c\n",*p);//e char *p="hello" p++; printf("%s\n",*p);//ello
#include <stdio.h> int main() { char *p="abcde"; printf("%c\n",*p); printf("%c\n",*p++); printf("%c\n",*p); printf("%c\n",*p++); printf("%c\n",*p); printf("%c\n",*(p++)); printf("%c\n",*p); printf("%c\n",*(p++)); printf("%c\n",*p); }//aabbccdde
- 在棧區定義恩恩一個指針p指向了文字常量區的內容,所以不可以用p對文字常量區的內容進行更改。
- printf是以\0結束的
- 字符串長度的計算
- strlen():計算\0之前的字符,不包括\0這個字符。包含頭文件#include <string.h>。
char str[10]="hello"; long int lengh=strlen(str); printf("lengh=%ld\n",lengh);
自己寫一個strlen的函數 #include <stdio.h> void mystrlen(int *lengh,const char *str) { while(*str!='\0') { *lengh+=1; str++; } } int main() { int l=0; char str[10]="hello"; mystrlen(&l,str); printf("%d\n",l); }
- 字符串的拷貝
- strcpy():將右邊的字符串完全拷貝到左邊的字符串里。而不是覆蓋一小部分。
char str1[10]="hello"; char str2[10]="asdaf"; strcpy(str2,str1);
- 注意的問題: 1. 左邊字符串的大小必須要大于右邊字符串的大小 2. 左邊的字符串不能使使用char *p定義出來的。
- strncpy():替換字符串前面的字符
#include <stdio.h> #include <stdio.h> int main() { char str1[20]="helloasas"; char str2[20]="asaaaworld"; strncpy(str1,str2,5); printf("%s\n",str1); }
- 字符串的比較
- strcmp(str1,str2),如果兩字符串相同,結果為0.
char str1[10]="hellb"; char str2[10]="hella"; strcmp(str1,str2);
- 如果左邊的字符串>右邊的字符串,結果是(左邊不同字符ascii碼減右邊對應位置字符ascii碼) - 如果編譯器低級 - 左>右,結果=1 - 右>左,結果=-1
- strncmp(str1,str2)
#include <stdio.h> int main() { char str1[20]="helloasas"; char str2[20]="hellaworld"; int result=strncmp(str1,str2,5); printf("%d\n",result);o-a }
- 字符串鏈接函數
- strcat:會將右邊字符串拼接到左邊的后面
char str1[10]="hello"; char str2[10]="world"; strcat(str1,str2);
- 注意:左邊的字符串要足夠大。
- strncat():只連接目標行數
#include <stdio.h> int main() { char str1[20]="helloasas"; char str2[20]="helloworld"; strncat(str1,str2,5); printf("%d\n",str1);//helloasashello }
字符串數組
- char str[2][10]={"hello","world"}
- 指針數組
char *p="123";
char *p1="nihao";
char *str[2]={p,p1};//*str1[2]={"123","hihao"};
程序內存空間分配
- 棧區:存儲局部變量
- 靜態區(全局區):靜態變量,全局變量
- 堆區:存放由程序員調用malloc函數時分配的空間。
- 文字常量區:常量字符串(只讀不能更改)
- 代碼二進制:代碼
結構體類型
- 可以將不同數據類型組合在一起的集合
- 定義方法
struct 結構體名
{
屬性變量;(特征變量)
}
struct Person
{
char name[10];
char sex;
int height;
float score;
};
struct Person//兩個加起來算一個數據類型。
//結構體變量的定義
struct Person person;
- 結構體變量初始方法
- .代表‘的’意思。
person.sex='m';
strcpy(person.name,"xxxx");
person.height=180;
person.score=100;
printf("sex=%c\nname=%s\nheight=%d\nscore=%f\n",person.sex,person.name,person.height,person.score);
- 初始化方法2
struct Person person={"xxx",'w',180,100}
- 初始化方法3
struct Person person2=person;
- 內存對齊:
- 如果結構體里的成員變量都是基本數據類型的成員,那么第一個成員的變量內存從內存偏移量為0的位置,后面的成員變量從內存偏移量是他本身字節數的倍數開始分配。
- 如果結構體成員變量里面是集合類型,數組,結構體,枚舉,那么成員變量。比如struct xxx{char ch,Int score}那么該結構體成員從內存偏移量是該結構體里面最大字節數的成員變量的倍數開始分配。
- 最后收尾的時候,總的字節數是最大成員變量(字節數)的倍數.
struct Person
{
char sex;//0
int height;//4--7
char ch;8(得9,根據條件3奧球倍數,所以為12)
};
struct Person
{
char sex;//0
char ch[10];//1--10
int height;//12--15
};
printf("%d",sizeof(struct Person));
- 包含結構體的內存對齊
#include <stdio.h>
int main()
{
struct Birthday
{
int year;//0-3
int month;//4-7===double month//8-15
int day;8-11======//16-19=>24
};
struct Person
{
char name[10];0-9
int score;12-15
char sex;16
struct Birthday birth;20-31//32====24-47=>48
};
struct Person person={"xxx",100,'m',{1990,1,1}};
printf("person.name=%s,birthday=%d/%d/%d\n",person.name,person.birth.year,person.birth.month,person.birth.day);
}
- 無名結構體
struct
{
int a;
char b;
}xx,xx1;
- 定義這個結構體數據類型的同時定義出來一個變量
struct Student
{
int score;
char sex;
}stu1[2]={{12,'m'},{13,'w'}};
- 結構體和指針的關系
struct Person;
{
int height;
char sex;
};
struct Person person;
struct Person *p=&person;
(*p).sex='m'
(*p).height='120'
printf("sex=%c,height=%d\n",person.sex,person.height);
p->sex='m'
p->height='120'
printf("sex=%c,height=%d\n",person.sex,person.height);
- 將現有的數據類型定義成想要的數據類型
- typedef
- typedef struct Person Person
- typedef struct Person * Pstu
typedef struct Stu { char name[10]; int num; }Stu(改結構體名),* Pstu;
struct Student { char name[10]; int num; }; typedef struct Student Student; Student stu{"xx",10}; printf("name=%s\nnum=%d\n",stu.name,stu.num);
- 數據類型的定義我們一般放在函數的外面供全局使用。
- 結構體數組
typedef struct Stu
{
char name[10];
int num;
}Stu;
int main()
{
int i;
Student stu[4]={{"xx",123},{"xx1",123},{"xx",122},{"xx2",124}}
for(i=0;i<4;i++)
{
printf("stu[%d].name=%s,stu[%d].num=%d",i,stu[i].name,i,stu[i].name);
}
}
//編寫程序比較結構體名字的大小進行排序
#include <stdio.h>
typedef struct Stu
{
char name[10];
int num;
}Stu;
int main()
{
int i,t;
Stu temp;
Stu stu[4]={{"xx3",123},{"xx1",123},{"xx4",122},{"xx2",124}};
for(i=0;i<4;i++)
{
printf("stu[%d].name=%s,stu[%d].num=%d\n",i,stu[i].name,i,stu[i].num);
}
for(i=0;i<3;i++)
{
t=strcmp(stu[i].name,stu[i+1].name);
if(t>0)
{
temp=stu[i];
stu[i]=stu[i+1];
stu[i+1]=temp;
}
}
for(i=0;i<4;i++)
{
printf("stu[%d].name=%s,stu[%d].num=%d\n",i,stu[i].name,i,stu[i].num);
}
}
- 什么時候形參使用傳地址:
- 在其他的函數空間訪問另外一個函數空間里面的數據時,并且是要改變這個內容時。
#include <stdio.h>
struct student
{
int num;
char name[10];
};
void changevalue(struct student *p)
{
(*p).num=8;
}
int main()
{
struct student stu;
stu.num=2;
changevalue(&stu);
printf("%d\n",stu.num);
}
//練習:自定義一個結構體數組,對數組里面的信息進行自動輸入賦值,再利用選擇排序進行整理
struct Student
{
char name[10];
int num;
};