Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Arrays,FunctionsadoptedfromKNKCProgramming:AModernApproach
요약
Copyright©2008W.W.Norton&Company.Allrightsreserved. 2
Array,배열• 하나이상의값을하나의변수에저장하는데이터타입• 선언• 값초기화와할당 (다양한방법이있음,자료참고)
• 인덱스• 활용• 배열의차원(dimension)
Copyright©2008W.W.Norton&Company.Allrightsreserved. 3
Array,배열:선언• 구성요소:• 타입: int,float,char,double,long,등• 변수명:변수이름짖는제약조건을따름• 배열크기:임의의양수,저장하고자하는값의개수만큼
Copyright©2008W.W.Norton&Company.Allrightsreserved. 4
int scores[100];타입 변수명 배열크기
Array,배열:초기화와할당 (상세내용은자료참고)
• 하나의값할당(변수선언후가능)
• 일부초기화(c99)
• 모든값초기화
• 배열크기미지정초기화
Copyright©2008W.W.Norton&Company.Allrightsreserved. 5
int scores[5];int scores[5];scores[2] = 80;
int a[5] = {99, 80, 70, 92, 100};
int a[5] = {[1] = 29, [3] = 7};
int a[] = {99, 80, 70, 92, 100};
5개의값을저장할수있는scores라는이름의정수형배열
Array,배열:인덱스• 배열의물리적표현
Copyright©2008W.W.Norton&Company.Allrightsreserved. 6
10개의값을저장할수있는a라는이름의배열
중요:0에서인덱스시작
int a[10];배열의물리적표현
값이저장된위치의주소
Array,배열:활용• 바코드계산프로그램
Copyright©2008W.W.Norton&Company.Allrightsreserved. 7
int i1, i2, i3, i4, i5;scanf("%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5);first_sum = d + i2 + i4 + j1 + j3 + j5;
int i[5];scanf("%1d%1d%1d%1d%1d", &i[0], &i[1], &i[2], &i[3], &i[4]);first_sum = d + i[1] +i[2];
int i[5];for(cnt = 0; cnt < 5; cnt++)
scanf(“%1d”, &i[cnt]);first_sum = d + i[1] +i[2];
Array,배열:차원• 1차원
• 2차원
Copyright©2008W.W.Norton&Company.Allrightsreserved. 8
int a[10];
int a[5][9];3차원이상도표현가능단,시각화는못함
Function,함수• 수행하고자하는일련의동작들에붙여진이름
• 프로그램을이해하고수정하는데도움이됨• Definition,정의• Calling,호출• Arguments,인자• return,리턴• recursion,재귀
Copyright©2008W.W.Norton&Company.Allrightsreserved. 9
Function,함수: Definition,정의• 호출하려는함수보다먼저함수의정의가작성되야함• 함수선언:• 함수의내용은없이앞으로사용할함수의이름과인자값을프로그램에등록함.• 작성스타일에따라항상필요하진않음.
• 함수정의:• 함수의실제내용이기록됨
Copyright©2008W.W.Norton&Company.Allrightsreserved. 10
Function,함수: Declaration,선언
Copyright©2008W.W.Norton&Company.Allrightsreserved. 11
#include <stdio.h>
int sum(int a, int b);int main(){
…}int sum(int a, int b)
{함수 내용
}
함수선언
함수정의
Function,함수: Definition,정의
Copyright©2008W.W.Norton&Company.Allrightsreserved. 12
return-type function-name ( parameters ){
declarationsstatements
}int sum(int a, int b){
int result=0;for( ; a <= b; a++)
sum += a;return result;
}
리턴데이터타입 함수이름 함수 내에서사용될인자들
함수내에서사용될변수선언
함수내에서실행할문장들
타입일치
Function,함수: Calling,호출• 코드내에함수이름을작성하여호출
Copyright©2008W.W.Norton&Company.Allrightsreserved. 13
int main(){…answer = sum(val1, val2);…
}
int sum(int a, int b){
…return result;
}
기존코드의흐름은위에서아래로실행
함수호출시함수정의위치로실행의흐름이이동함
Function,함수: Arguments,인자• 함수밖에서정의된값으로함수내에서활용할변수이름
Copyright©2008W.W.Norton&Company.Allrightsreserved. 14
int main(){…answer = sum(val1, val2);…
}
int sum(int a, int b){
…return a + b;
}
메인코드에서선언된 val1과 val2를sum이라는함수에활용할수있도록인자로넣었음
함수에서활용할변수이름은메인코드의변수이름과달라도됨
Function,함수:종합예제
Copyright©2008W.W.Norton&Company.Allrightsreserved. 15
#include <stdio.h>int sum(int a, int b);int main(){
int val1, val2, answer;printf(“Input two numbers in increasing order: “);scanf(“%d %d”, &val1, &val2);answer = sum(val1, val2);printf(“The sum is %d\n”, answer);
}
int sum(int a, int b){
int result=0;for( ; a <= b; a++)
sum += a;return result;
}
호출
결과값반환
Function,함수: Recursion,재귀• 함수가호출되면해당코드를실행하고결과를리턴함
• 함수가자기스스로를다시호출하는것이가능함• 팩토리얼을기억해보기바람
Copyright©2008W.W.Norton&Company.Allrightsreserved. 16
int fact(int n){
if (n <= 1)return 1;
else
return n * fact(n - 1);}
다시호출
WorkshopUsetheworksheet
Copyright©2008W.W.Norton&Company.Allrightsreserved. 17
ArraysadoptedfromKNKCProgramming:AModernApproach
ScalarVariablesversusAggregateVariables• Sofar,theonlyvariableswe’veseenarescalar: capableofholdingasingledataitem.스칼라만다룸,한번에한값만저장가능
• Calsosupportsaggregate variables,whichcanstorecollectionsofvalues.집합변수지원,하나이상의다른값저장가능
• TherearetwokindsofaggregatesinC:arraysandstructures.두종류가있음,배열(array),구조체(structure)
Copyright©2008W.W.Norton&Company.Allrightsreserved. 19
One-DimensionalArrays• Anarray isadatastructurecontaininganumberofdatavalues,allofwhichhavethesametype.같은타입의값이하나의배열에저장
• Thesevalues,knownaselements, canbeindividuallyselectedbytheirpositionwithinthearray. 각값을요소라부름
• Thesimplestkindofarrayhasjustonedimension.1차원배열이가장간단함
• Theelementsofaone-dimensionalarraya areconceptuallyarrangedoneafteranotherinasinglerow(orcolumn):개념적으로 1줄짜리바둑판으로표현됨
Copyright©2008W.W.Norton&Company.Allrightsreserved. 20
One-DimensionalArrays• Todeclareanarray,wemustspecifythetype ofthearray’selementsandthenumber ofelements:배열선언시배열크기명시
int a[10];
• Theelementsmaybeofanytype;thelengthofthearraycanbeany(integer)constantexpression.어떤타입도사용가능,고정된크기를갖음
• Usingamacrotodefinethelengthofanarrayisanexcellentpractice:배열의크기는매크로로정의하는것이바람직함
#define N 10…int a[N];
Copyright©2008W.W.Norton&Company.Allrightsreserved. 21
ArraySubscripting• Toaccessanarrayelement,writethearraynamefollowedbyanintegervalueinsquarebrackets.참조법:변수이름과대괄호에수를넣음
• Thisisreferredtoassubscripting orindexing thearray.참조할배열의위치를인덱스라고부름
• Theelementsofanarrayoflengthn areindexedfrom0ton – 1.배열의크기가 n일때인덱스시작과끝값은 0과 n-1임
• Ifa isanarrayoflength10,itselementsaredesignatedbya[0],a[1],…,a[9]:크기 10일때시작은 0끝은 9
Copyright©2008W.W.Norton&Company.Allrightsreserved. 22
ArraySubscripting• Expressionsoftheforma[i] arelvalues,sotheycanbeusedinthesamewayasordinaryvariables:a[i]은 lvalue이기때문에값을할당받을수있음
a[0] = 1;printf("%d\n", a[5]);++a[i];
Copyright©2008W.W.Norton&Company.Allrightsreserved. 23
인덱스가실제저장된값이아님!!
ArraySubscripting• Manyprogramscontainfor loopswhosejobistoperformsomeoperationoneveryelementinanarray.for 루프의사용예
• Examplesoftypicaloperationsonanarraya oflengthN:for (i = 0; i < N; i++)
a[i] = 0; /* clears a */
for (i = 0; i < N; i++)scanf("%d", &a[i]); /* reads data into a */
for (i = 0; i < N; i++)sum += a[i]; /* sums the elements of a */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 24
ArraySubscripting• Cdoesn’trequirethatsubscriptboundsbechecked;ifasubscriptgoesoutofrange,theprogram’sbehaviorisundefined.인덱스경계를검사하지않음;범위를넘으면오동작을함
• Acommonmistake:forgettingthatanarraywithn elementsisindexedfrom0ton – 1,not1ton:흔한실수:인덱스를 1부터시작
int a[10], i;
for (i = 1; i <= 10; i++)a[i] = 0;
Withsomecompilers,thisinnocent-lookingfor statementcausesaninfiniteloop.어떤컴파일러의경우무한루프에빠지게됨.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 25
ArraySubscripting• Anarraysubscriptmaybeanyintegerexpression:인덱스는정수표현식으로사용가능
a[i+j*10] = 0;
• Theexpressioncanevenhavesideeffects:수식에사이드이펙트가있어도됨
i = 0;while (i < N)a[i++] = 0;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 26
ArraySubscripting• Becarefulwhenanarraysubscripthasasideeffect:인덱스값에사이드이펙트가있는경우주의해야함
i = 0;while (i < N)a[i] = b[i++];
• Theexpressiona[i] = b[i++] accessesthevalueofi andalsomodifiesi,causingundefinedbehavior.정의되지않은동작
• Theproblemcanbeavoidedbyremovingtheincrementfromthesubscript:인덱스에서증가값을분리해서문제해결가능
for (i = 0; i < N; i++)a[i] = b[i];
Copyright©2008W.W.Norton&Company.Allrightsreserved. 27
ArrayInitialization• Anarray,likeanyothervariable,canbegivenaninitialvalueatthetimeit’sdeclared.변수선언시값을할당하여초기화할수있음
• Themostcommonformofarrayinitializerisalistofconstantexpressionsenclosedinbracesandseparatedbycommas:흔한초기화방법:중괄호와값그리고쉼표로구분
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 28
ArrayInitialization• Iftheinitializerisshorterthanthearray,theremainingelementsofthearrayaregiventhevalue0:int a[10] = {1, 2, 3, 4, 5, 6};/* initial value of a is {1, 2, 3, 4, 5, 6, 0, 0, 0, 0} */
• Usingthisfeature,wecaneasilyinitializeanarraytoallzeros:int a[10] = {0};/* initial value of a is {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} */
There’sasingle0insidethebracesbecauseit’sillegalforaninitializertobecompletelyempty.
• It’salsoillegalforaninitializertobelongerthanthearrayitinitializes.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 29
ArrayInitialization• Ifaninitializerispresent,thelengthofthearraymaybeomitted:int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
• Thecompilerusesthelengthoftheinitializertodeterminehowlongthearrayis.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 30
DesignatedInitializers(C99)• It’softenthecasethatrelativelyfewelementsofanarrayneedtobeinitializedexplicitly;theotherelementscanbegivendefaultvalues.• Anexample:int a[15] ={0, 0, 29, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 48};
• Foralargearray,writinganinitializerinthisfashionistediousanderror-prone.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 31
DesignatedInitializers(C99)• C99’sdesignatedinitializerscanbeusedtosolvethisproblem.
• Here’showwecouldredothepreviousexampleusingadesignatedinitializer:int a[15] = {[2] = 29, [9] = 7, [14] = 48};
• Eachnumberinbracketsissaidtobeadesignator.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 32
DesignatedInitializers(C99)• Designatedinitializersareshorterandeasiertoread(atleastforsomearrays).
• Also,theorderinwhichtheelementsarelistednolongermatters.
• Anotherwaytowritethepreviousexample:int a[15] = {[14] = 48, [9] = 7, [2] = 29};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 33
DesignatedInitializers(C99)• Designatorsmustbeintegerconstantexpressions.
• Ifthearraybeinginitializedhaslengthn,eachdesignatormustbebetween0andn – 1.
• Ifthelengthofthearrayisomitted,adesignatorcanbeanynonnegativeinteger.• Thecompilerwilldeducethelengthofthearrayfromthelargestdesignator.
• Thefollowingarraywillhave24elements:int b[] = {[5] = 10, [23] = 13, [11] = 36, [15] = 29};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 34
DesignatedInitializers(C99)• Aninitializermayuseboththeolder(element-by-element)techniqueandthenewer(designated)technique:int c[10] = {5, 1, 9, [4] = 3, 7, 2, [8] = 6};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 35
Usingthesizeof OperatorwithArrays• Thesizeof operatorcandeterminethesizeofanarray(inbytes).• Ifa isanarrayof10integers,thensizeof(a) istypically40(assumingthateachintegerrequiresfourbytes).• Wecanalsousesizeof tomeasurethesizeofanarrayelement,suchasa[0].
• Dividingthearraysizebytheelementsizegivesthelengthofthearray:sizeof(a) / sizeof(a[0])
Copyright©2008W.W.Norton&Company.Allrightsreserved. 36
Usingthesizeof OperatorwithArrays• Someprogrammersusethisexpressionwhenthelengthofthearrayisneeded.• Aloopthatclearsthearraya:for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)a[i] = 0;
Notethattheloopdoesn’thavetobemodifiedifthearraylengthshouldchangeatalaterdate.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 37
Usingthesizeof OperatorwithArrays• Somecompilersproduceawarningmessagefortheexpressioni< sizeof(a) / sizeof(a[0]).
• Thevariablei probablyhastypeint (asignedtype),whereassizeof producesavalueoftypesize_t (anunsignedtype).
• Comparingasignedintegerwithanunsignedintegercanbedangerous,butinthiscaseit’ssafe.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 38
Usingthesizeof OperatorwithArrays• Toavoidawarning,wecanaddacastthatconvertssizeof(a)/ sizeof(a[0]) toasignedinteger:for (i = 0; i < (int) (sizeof(a) / sizeof(a[0])); i++)
a[i] = 0;
• Definingamacroforthesizecalculationisoftenhelpful:#define SIZE ((int) (sizeof(a) / sizeof(a[0])))
for (i = 0; i < SIZE; i++)a[i] = 0;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 39
MultidimensionalArrays• Anarraymayhaveanynumberofdimensions.
• Thefollowingdeclarationcreatesatwo-dimensionalarray(amatrix, inmathematicalterminology):int m[5][9];
• m has5rowsand9columns.Bothrowsandcolumnsareindexedfrom0:
Copyright©2008W.W.Norton&Company.Allrightsreserved. 40
MultidimensionalArrays• Toaccesstheelementofm inrowi,columnj,wemustwritem[i][j].
• Theexpressionm[i] designatesrowi ofm,andm[i][j] thenselectselementj inthisrow.
• Resistthetemptationtowritem[i,j] insteadofm[i][j].
• Ctreatsthecommaasanoperatorinthiscontext,som[i,j] isthesameasm[j].
Copyright©2008W.W.Norton&Company.Allrightsreserved. 41
MultidimensionalArrays• Althoughwevisualizetwo-dimensionalarraysastables,that’snotthewaythey’reactuallystoredincomputermemory.
• Cstoresarraysinrow-majororder, withrow0first,thenrow1,andsoforth.• Howthem arrayisstored:
Copyright©2008W.W.Norton&Company.Allrightsreserved. 42
MultidimensionalArrays• Nestedfor loopsareidealforprocessingmultidimensionalarrays.
• Considertheproblemofinitializinganarrayforuseasanidentitymatrix.Apairofnestedfor loopsisperfect:#define N 10
double ident[N][N];int row, col;
for (row = 0; row < N; row++)for (col = 0; col < N; col++)
if (row == col)ident[row][col] = 1.0;
elseident[row][col] = 0.0;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 43
InitializingaMultidimensionalArray• Wecancreateaninitializerforatwo-dimensionalarraybynestingone-dimensionalinitializers:int m[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0},{0, 1, 0, 1, 1, 0, 0, 1, 0},{1, 1, 0, 1, 0, 0, 0, 1, 0},{1, 1, 0, 1, 0, 0, 1, 1, 1}};
• Initializersforhigher-dimensionalarraysareconstructedinasimilarfashion.• Cprovidesavarietyofwaystoabbreviateinitializersformultidimensionalarrays
Copyright©2008W.W.Norton&Company.Allrightsreserved. 44
InitializingaMultidimensionalArray• Ifaninitializerisn’tlargeenoughtofillamultidimensionalarray,theremainingelementsaregiventhevalue0.• Thefollowinginitializerfillsonlythefirstthreerowsofm;thelasttworowswillcontainzeros:int m[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1, 0},{0, 1, 0, 1, 1, 0, 0, 1, 0}};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 45
InitializingaMultidimensionalArray• Ifaninnerlistisn’tlongenoughtofillarow,theremainingelementsintherowareinitializedto0:int m[5][9] = {{1, 1, 1, 1, 1, 0, 1, 1, 1},
{0, 1, 0, 1, 0, 1, 0, 1},{0, 1, 0, 1, 1, 0, 0, 1},{1, 1, 0, 1, 0, 0, 0, 1},{1, 1, 0, 1, 0, 0, 1, 1, 1}};
Copyright©2008W.W.Norton&Company.Allrightsreserved. 46
InitializingaMultidimensionalArray• Wecanevenomittheinnerbraces:int m[5][9] = {1, 1, 1, 1, 1, 0, 1, 1, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0,0, 1, 0, 1, 1, 0, 0, 1, 0,1, 1, 0, 1, 0, 0, 0, 1, 0,1, 1, 0, 1, 0, 0, 1, 1, 1};
Oncethecompilerhasseenenoughvaluestofillonerow,itbeginsfillingthenext.
• Omittingtheinnerbracescanberisky,sinceanextraelement(orevenworse,amissingelement)willaffecttherestoftheinitializer.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 47
InitializingaMultidimensionalArray• C99’sdesignatedinitializersworkwithmultidimensionalarrays.
• Howtocreate2× 2identitymatrix:double ident[2][2] = {[0][0] = 1.0, [1][1] = 1.0};
Asusual,allelementsforwhichnovalueisspecifiedwilldefaulttozero.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 48
ConstantArrays• Anarraycanbemade“constant”bystartingitsdeclarationwiththewordconst:const char hex_chars[] ={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F'};
• Anarraythat’sbeendeclaredconst shouldnotbemodifiedbytheprogram.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 49
ConstantArrays• Advantagesofdeclaringanarraytobeconst:• Documentsthattheprogramwon’tchangethearray.• Helpsthecompilercatcherrors.
• const isn’tlimitedtoarrays,butit’sparticularlyusefulinarraydeclarations.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 50
Variable-LengthArrays(C99)• InC89,thelengthofanarrayvariablemustbespecifiedbyaconstantexpression.
• InC99,however,it’ssometimespossibletouseanexpressionthat’snot constant.• Thereverse2.c program—amodificationofreverse.c—illustratesthisability.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 51
Variable-LengthArrays(C99)• Thearraya inthereverse2.c programisanexampleofavariable-lengtharray(orVLA).
• ThelengthofaVLAiscomputedwhentheprogramisexecuted.
• ThechiefadvantageofaVLAisthataprogramcancalculateexactlyhowmanyelementsareneeded.
• Iftheprogrammermakesthechoice,it’slikelythatthearraywillbetoolong(wastingmemory)ortooshort(causingtheprogramtofail).
Copyright©2008W.W.Norton&Company.Allrightsreserved. 52
Variable-LengthArrays(C99)• ThelengthofaVLAdoesn’thavetobespecifiedbyasinglevariable.Arbitraryexpressionsarelegal:int a[3*i+5];int b[j+k];
• Likeotherarrays,VLAscanbemultidimensional:int c[m][n];
• RestrictionsonVLAs:• Can’thavestaticstorageduration(discussedinChapter18).• Can’thaveaninitializer.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 53
FunctionsadoptedfromKNKCProgramming:AModernApproach
Introduction• Afunctionisaseriesofstatementsthathavebeengroupedtogetherandgivenaname.
• Eachfunctionisessentiallyasmallprogram,withitsowndeclarationsandstatements.
• Advantagesoffunctions:• Aprogramcanbedividedintosmallpiecesthatareeasiertounderstandandmodify.
• Wecanavoidduplicatingcodethat’susedmorethanonce.• Afunctionthatwasoriginallypartofoneprogramcanbereusedinotherprograms.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 55
DefiningandCallingFunctions• Beforewegoovertheformalrulesfordefiningafunction,let’slookatthreesimpleprogramsthatdefinefunctions.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 56
Program:ComputingAverages• Afunctionnamedaverage thatcomputestheaverageoftwodouble values:double average(double a, double b){return (a + b) / 2;
}
• Theworddouble atthebeginningisthereturntype ofaverage.
• Theidentifiersa andb (thefunction’sparameters)representthenumbersthatwillbesuppliedwhenaverage iscalled.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 57
Program:ComputingAverages• Everyfunctionhasanexecutablepart,calledthebody, whichisenclosedinbraces.• Thebodyofaverage consistsofasinglereturn statement.
• Executingthisstatementcausesthefunctionto“return”totheplacefromwhichitwascalled;thevalueof(a + b) / 2 willbethevaluereturnedbythefunction.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 58
Program:ComputingAverages• Afunctioncallconsistsofafunctionnamefollowedbyalistofarguments.• average(x, y) isacalloftheaverage function.
• Argumentsareusedtosupplyinformationtoafunction.• Thecallaverage(x, y) causesthevaluesofx andy tobecopiedintotheparametersa andb.
• Anargumentdoesn’thavetobeavariable;anyexpressionofacompatibletypewilldo.• average(5.1, 8.9) andaverage(x/2, y/3) arelegal.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 59
Program:ComputingAverages• We’llputthecallofaverage intheplacewhereweneedtousethereturnvalue.• Astatementthatprintstheaverageofx andy:printf("Average: %g\n", average(x, y));
Thereturnvalueofaverage isn’tsaved;theprogramprintsitandthendiscardsit.
• Ifwehadneededthereturnvaluelaterintheprogram,wecouldhavecaptureditinavariable:avg = average(x, y);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 60
Program:ComputingAverages• Theaverage.c programreadsthreenumbersandusestheaverage functiontocomputetheiraverages,onepairatatime:Enter three numbers: 3.5 9.6 10.2Average of 3.5 and 9.6: 6.55Average of 9.6 and 10.2: 9.9Average of 3.5 and 10.2: 6.85
Copyright©2008W.W.Norton&Company.Allrightsreserved. 61
average.c/* Computes pairwise averages of three numbers */
#include <stdio.h>
double average(double a, double b){return (a + b) / 2;
}
int main(void){double x, y, z;
printf("Enter three numbers: ");scanf("%lf%lf%lf", &x, &y, &z);printf("Average of %g and %g: %g\n", x, y, average(x, y));printf("Average of %g and %g: %g\n", y, z, average(y, z));printf("Average of %g and %g: %g\n", x, z, average(x, z));
return 0;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 62
Program:PrintingaCountdown• Toindicatethatafunctionhasnoreturnvalue,wespecifythatitsreturntypeisvoid:void print_count(int n){printf("T minus %d and counting\n", n);
}
• void isatypewithnovalues.• Acallofprint_countmustappearinastatementbyitself:print_count(i);
• Thecountdown.c programcallsprint_count 10timesinsidealoop.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 63
countdown.c
/* Prints a countdown */
#include <stdio.h>
void print_count(int n){printf("T minus %d and counting\n", n);
}
int main(void){int i;
for (i = 10; i > 0; --i)print_count(i);
return 0;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 64
Program:PrintingaPun(Revisited)• Whenafunctionhasnoparameters,thewordvoid isplacedinparenthesesafterthefunction’sname:void print_pun(void){printf("To C, or not to C: that is the question.\n");
}
• Tocallafunctionwithnoarguments,wewritethefunction’sname,followedbyparentheses:print_pun();
Theparenthesesmust bepresent.• Thepun2.c programteststheprint_pun function.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 65
pun2.c
/* Prints a bad pun */
#include <stdio.h>
void print_pun(void){printf("To C, or not to C: that is the question.\n");
}
int main(void){print_pun();return 0;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 66
FunctionDefinitions• Generalformofafunctiondefinition:return-type function-name ( parameters ){
declarationsstatements
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 67
FunctionDefinitions• Thereturntypeofafunctionisthetypeofvaluethatthefunctionreturns.
• Rulesgoverningthereturntype:• Functionsmaynotreturnarrays.• Specifyingthatthereturntypeisvoid indicatesthatthefunctiondoesn’treturnavalue.
• IfthereturntypeisomittedinC89,thefunctionispresumedtoreturnavalueoftypeint.
• InC99,omittingthereturntypeisillegal.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 68
FunctionDefinitions• Asamatterofstyle,someprogrammersputthereturntypeabove thefunctionname:doubleaverage(double a, double b){return (a + b) / 2;
}
• Puttingthereturntypeonaseparatelineisespeciallyusefulifthereturntypeislengthy,likeunsigned long int.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 69
FunctionDefinitions• Afterthefunctionnamecomesalistofparameters.
• Eachparameterisprecededbyaspecificationofitstype;parametersareseparatedbycommas.• Ifthefunctionhasnoparameters,thewordvoid shouldappearbetweentheparentheses.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 70
FunctionDefinitions• Thebodyofafunctionmayincludebothdeclarationsandstatements.• Analternativeversionoftheaverage function:double average(double a, double b){double sum; /* declaration */
sum = a + b; /* statement */return sum / 2; /* statement */
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 71
FunctionDefinitions• Variablesdeclaredinthebodyofafunctioncan’tbeexaminedormodifiedbyotherfunctions.
• InC89,variabledeclarationsmustcomefirst,beforeallstatementsinthebodyofafunction.
• InC99,variabledeclarationsandstatementscanbemixed,aslongaseachvariableisdeclaredpriortothefirststatementthatusesthevariable.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 72
FunctionDefinitions• Thebodyofafunctionwhosereturntypeisvoid (a“voidfunction”)canbeempty:void print_pun(void){}
• Leavingthebodyemptymaymakesenseasatemporarystepduringprogramdevelopment.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 73
FunctionCalls• Afunctioncallconsistsofafunctionnamefollowedbyalistofarguments,enclosedinparentheses:average(x, y)print_count(i)print_pun()
• Iftheparenthesesaremissing,thefunctionwon’tbecalled:print_pun; /*** WRONG ***/
Thisstatementislegalbuthasnoeffect.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 74
FunctionCalls• Acallofavoid functionisalwaysfollowedbyasemicolontoturnitintoastatement:print_count(i);print_pun();
• Acallofanon-void functionproducesavaluethatcanbestoredinavariable,tested,printed,orusedinsomeotherway:avg = average(x, y);if (average(x, y) > 0)printf("Average is positive\n");
printf("The average is %g\n", average(x, y));
Copyright©2008W.W.Norton&Company.Allrightsreserved. 75
FunctionCalls• Thevaluereturnedbyanon-void functioncanalwaysbediscardedifit’snotneeded:average(x, y); /* discards return value */
Thiscallisanexampleofanexpressionstatement:astatementthatevaluatesanexpressionbutthendiscardstheresult.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 76
FunctionCalls• Ignoringthereturnvalueofaverage isanoddthingtodo,butforsomefunctionsitmakessense.• printf returnsthenumberofcharactersthatitprints.
• Afterthefollowingcall,num_chars willhavethevalue9:num_chars = printf("Hi, Mom!\n");
• We’llnormallydiscardprintf’sreturnvalue:printf("Hi, Mom!\n");/* discards return value */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 77
FunctionCalls• Tomakeitclearthatwe’redeliberatelydiscardingthereturnvalueofafunction,Callowsustoput(void) beforethecall:(void) printf("Hi, Mom!\n");
• Using(void)makesitcleartoothersthatyoudeliberatelydiscardedthereturnvalue,notjustforgotthattherewasone.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 78
Program:TestingWhetheraNumberIsPrime• Theprime.c programtestswhetheranumberisprime:Enter a number: 34Not prime
• Theprogramusesafunctionnamedis_prime thatreturnstrue ifitsparameterisaprimenumberandfalse ifitisn’t.
• is_prime dividesitsparametern byeachofthenumbersbetween2andthesquarerootofn;iftheremainderisever0,nisn’tprime.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 79
prime.c
/* Tests whether a number is prime */
#include <stdbool.h> /* C99 only */#include <stdio.h>
bool is_prime(int n){int divisor;
if (n <= 1)return false;
for (divisor = 2; divisor * divisor <= n; divisor++)if (n % divisor == 0)return false;
return true;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 80
int main(void){int n;
printf("Enter a number: ");scanf("%d", &n);if (is_prime(n))printf("Prime\n");
elseprintf("Not prime\n");
return 0;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 81
FunctionDeclarations• Cdoesn’trequirethatthedefinitionofafunctionprecedeitscalls.• Supposethatwerearrangetheaverage.c programbyputtingthedefinitionofaverage after thedefinitionofmain.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 82
FunctionDeclarations#include <stdio.h>
int main(void){double x, y, z;
printf("Enter three numbers: ");scanf("%lf%lf%lf", &x, &y, &z);printf("Average of %g and %g: %g\n", x, y, average(x, y));printf("Average of %g and %g: %g\n", y, z, average(y, z));printf("Average of %g and %g: %g\n", x, z, average(x, z));
return 0;}
double average(double a, double b){return (a + b) / 2;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 83
FunctionDeclarations• Whenthecompilerencountersthefirstcallofaverage inmain,ithasnoinformationaboutthefunction.
• Insteadofproducinganerrormessage,thecompilerassumesthataverage returnsanint value.
• Wesaythatthecompilerhascreatedanimplicitdeclaration ofthefunction.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 84
FunctionDeclarations• Thecompilerisunabletocheckthatwe’repassingaverage therightnumberofargumentsandthattheargumentshavethepropertype.• Instead,itperformsthedefaultargumentpromotionsandhopesforthebest.• Whenitencountersthedefinitionofaverage laterintheprogram,thecompilernoticesthatthefunction’sreturntypeisactuallydouble,notint,andsowegetanerrormessage.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 85
FunctionDeclarations• Onewaytoavoidtheproblemofcall-before-definitionistoarrangetheprogramsothatthedefinitionofeachfunctionprecedesallitscalls.• Unfortunately,suchanarrangementdoesn’talwaysexist.
• Evenwhenitdoes,itmaymaketheprogramhardertounderstandbyputtingitsfunctiondefinitionsinanunnaturalorder.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 86
FunctionDeclarations• Fortunately,Coffersabettersolution:declareeachfunctionbeforecallingit.• Afunctiondeclaration providesthecompilerwithabriefglimpseatafunctionwhosefulldefinitionwillappearlater.• Generalformofafunctiondeclaration:return-type function-name ( parameters ) ;
• Thedeclarationofafunctionmustbeconsistentwiththefunction’sdefinition.• Here’stheaverage.c programwithadeclarationofaverage added.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 87
FunctionDeclarations#include <stdio.h>
double average(double a, double b); /* DECLARATION */
int main(void){double x, y, z;
printf("Enter three numbers: ");scanf("%lf%lf%lf", &x, &y, &z);printf("Average of %g and %g: %g\n", x, y, average(x, y));printf("Average of %g and %g: %g\n", y, z, average(y, z));printf("Average of %g and %g: %g\n", x, z, average(x, z));
return 0;}
double average(double a, double b) /* DEFINITION */{return (a + b) / 2;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 88
FunctionDeclarations• Functiondeclarationsofthekindwe’rediscussingareknownasfunctionprototypes.
• Calsohasanolderstyleoffunctiondeclarationinwhichtheparenthesesareleftempty.
• Afunctionprototypedoesn’thavetospecifythenamesofthefunction’sparameters,aslongastheirtypesarepresent:double average(double, double);
• It’susuallybestnottoomitparameternames.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 89
FunctionDeclarations• C99hasadoptedtherulethateitheradeclarationoradefinitionofafunctionmustbepresentpriortoanycallofthefunction.
• Callingafunctionforwhichthecompilerhasnotyetseenadeclarationordefinitionisanerror.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 90
Arguments• InC,argumentsarepassedbyvalue: whenafunctioniscalled,eachargumentisevaluatedanditsvalueassignedtothecorrespondingparameter.• Sincetheparametercontainsacopyoftheargument’svalue,anychangesmadetotheparameterduringtheexecutionofthefunctiondon’taffecttheargument.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 91
Arguments• Thefactthatargumentsarepassedbyvaluehasbothadvantagesanddisadvantages.
• Sinceaparametercanbemodifiedwithoutaffectingthecorrespondingargument,wecanuseparametersasvariableswithinthefunction,reducingthenumberofgenuinevariablesneeded.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 92
Arguments• Considerthefollowingfunction,whichraisesanumberx toapowern:int power(int x, int n){int i, result = 1;
for (i = 1; i <= n; i++)result = result * x;
return result;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 93
Arguments• Sincen isacopy oftheoriginalexponent,thefunctioncansafelymodifyit,removingtheneedfori:int power(int x, int n){int result = 1;
while (n-- > 0)result = result * x;
return result;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 94
Arguments• C’srequirementthatargumentsbepassedbyvaluemakesitdifficulttowritecertainkindsoffunctions.• Supposethatweneedafunctionthatwilldecomposeadouble valueintoanintegerpartandafractionalpart.
• Sinceafunctioncan’treturn twonumbers,wemighttrypassingapairofvariablestothefunctionandhavingitmodifythem:void decompose(double x, long int_part,
double frac_part){
int_part = (long) x;frac_part = x - int_part;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 95
Arguments• Acallofthefunction:decompose(3.14159, i, d);
• Unfortunately,i andd won’tbeaffectedbytheassignmentstoint_part andfrac_part.
• Chapter11showshowtomakedecompose workcorrectly.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 96
ArgumentConversions• Callowsfunctioncallsinwhichthetypesoftheargumentsdon’tmatchthetypesoftheparameters.
• Therulesgoverninghowtheargumentsareconverteddependonwhetherornotthecompilerhasseenaprototypeforthefunction(orthefunction’sfulldefinition)priortothecall.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 97
ArgumentConversions• Thecompilerhasencounteredaprototypepriortothecall.
• Thevalueofeachargumentisimplicitlyconvertedtothetypeofthecorrespondingparameterasifbyassignment.• Example:Ifanint argumentispassedtoafunctionthatwasexpectingadouble,theargumentisconvertedtodoubleautomatically.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 98
ArgumentConversions• Thecompilerhasnotencounteredaprototypepriortothecall.
• Thecompilerperformsthedefaultargumentpromotions:• float argumentsareconvertedtodouble.• Theintegralpromotionsareperformed,causingchar andshort argumentstobeconvertedtoint.(InC99,theintegerpromotionsareperformed.)
Copyright©2008W.W.Norton&Company.Allrightsreserved. 99
ArgumentConversions• Relyingonthedefaultargumentpromotionsisdangerous.
• Example:#include <stdio.h>
int main(void){
double x = 3.0;printf("Square: %d\n", square(x));
return 0;}
int square(int n){
return n * n;}
• Atthetimesquare iscalled,thecompilerdoesn’tknowthatitexpectsanargumentoftypeint.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 100
ArgumentConversions• Instead,thecompilerperformsthedefaultargumentpromotionsonx,withnoeffect.
• Sinceit’sexpectinganargumentoftypeint buthasbeengivenadouble valueinstead,theeffectofcallingsquare isundefined.
• Theproblemcanbefixedbycastingsquare’sargumenttothepropertype:printf("Square: %d\n", square((int) x));
• Amuchbettersolutionistoprovideaprototypeforsquare beforecallingit.
• InC99,callingsquare withoutfirstprovidingadeclarationordefinitionofthefunctionisanerror.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 101
ArrayArguments• Whenafunctionparameterisaone-dimensionalarray,thelengthofthearraycanbeleftunspecified:int f(int a[]) /* no length specified */{…
}
• Cdoesn’tprovideanyeasywayforafunctiontodeterminethelengthofanarraypassedtoit.• Instead,we’llhavetosupplythelength—ifthefunctionneedsit—asanadditionalargument.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 102
ArrayArguments• Example:int sum_array(int a[], int n){int i, sum = 0;
for (i = 0; i < n; i++)sum += a[i];
return sum;}
• Sincesum_array needstoknowthelengthofa,wemustsupplyitasasecondargument.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 103
ArrayArguments• Theprototypeforsum_array hasthefollowingappearance:int sum_array(int a[], int n);
• Asusual,wecanomittheparameternamesifwewish:int sum_array(int [], int);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 104
ArrayArguments• Whensum_array iscalled,thefirstargumentwillbethenameofanarray,andthesecondwillbeitslength:#define LEN 100
int main(void){
int b[LEN], total;…total = sum_array(b, LEN);…
}
• Noticethatwedon’tputbracketsafteranarraynamewhenpassingittoafunction:total = sum_array(b[], LEN); /*** WRONG ***/
Copyright©2008W.W.Norton&Company.Allrightsreserved. 105
ArrayArguments• Afunctionhasnowaytocheckthatwe’vepasseditthecorrectarraylength.
• Wecanexploitthisfactbytellingthefunctionthatthearrayissmallerthanitreallyis.• Supposethatwe’veonlystored50numbersintheb array,eventhoughitcanhold100.
• Wecansumjustthefirst50elementsbywritingtotal = sum_array(b, 50);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 106
ArrayArguments• Becarefulnottotellafunctionthatanarrayargumentislargerthanitreallyis:total = sum_array(b, 150); /*** WRONG ***/
sum_array willgopasttheendofthearray,causingundefinedbehavior.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 107
ArrayArguments• Afunctionisallowedtochangetheelementsofanarrayparameter,andthechangeisreflectedinthecorrespondingargument.• Afunctionthatmodifiesanarraybystoringzerointoeachofitselements:void store_zeros(int a[], int n){int i;
for (i = 0; i < n; i++) a[i] = 0;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 108
ArrayArguments• Acallofstore_zeros:store_zeros(b, 100);
• TheabilitytomodifytheelementsofanarrayargumentmayseemtocontradictthefactthatCpassesargumentsbyvalue.
• Chapter12explainswhythere’sactuallynocontradiction.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 109
ArrayArguments• Ifaparameterisamultidimensionalarray,onlythelengthofthefirstdimensionmaybeomitted.• Ifwerevisesum_array sothata isatwo-dimensionalarray,wemustspecifythenumberofcolumnsina:#define LEN 10
int sum_two_dimensional_array(int a[][LEN], int n){
int i, j, sum = 0;
for (i = 0; i < n; i++)for (j = 0; j < LEN; j++)
sum += a[i][j];
return sum;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 110
ArrayArguments• Notbeingabletopassmultidimensionalarrayswithanarbitrarynumberofcolumnscanbeanuisance.
• Wecanoftenworkaroundthisdifficultybyusingarraysofpointers.
• C99’svariable-lengtharrayparametersprovideanevenbettersolution.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 111
Variable-LengthArrayParameters(C99)• C99allowstheuseofvariable-lengtharraysasparameters.• Considerthesum_array function:int sum_array(int a[], int n){…
}
Asitstandsnow,there’snodirectlinkbetweenn andthelengthofthearraya.• Althoughthefunctionbodytreatsn asa’slength,theactuallengthofthearraycouldbelargerorsmallerthann.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 112
Variable-LengthArrayParameters(C99)• Usingavariable-lengtharrayparameter,wecanexplicitlystatethata’slengthisn:int sum_array(int n, int a[n]){…
}
• Thevalueofthefirstparameter(n)specifiesthelengthofthesecondparameter(a).• Notethattheorderoftheparametershasbeenswitched;orderisimportantwhenvariable-lengtharrayparametersareused.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 113
Variable-LengthArrayParameters(C99)• Thereareseveralwaystowritetheprototypeforthenewversionofsum_array.
• Onepossibilityistomakeitlookexactlylikethefunctiondefinition:int sum_array(int n, int a[n]); /* Version 1 */
• Anotherpossibilityistoreplacethearraylengthbyanasterisk(*):int sum_array(int n, int a[*]); /* Version 2a */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 114
Variable-LengthArrayParameters(C99)• Thereasonforusingthe* notationisthatparameternamesareoptionalinfunctiondeclarations.
• Ifthenameofthefirstparameterisomitted,itwouldn’tbepossibletospecifythatthelengthofthearrayisn,butthe*providesacluethatthelengthofthearrayisrelatedtoparametersthatcomeearlierinthelist:int sum_array(int, int [*]); /* Version 2b */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 115
Variable-LengthArrayParameters(C99)• It’salsolegaltoleavethebracketsempty,aswenormallydowhendeclaringanarrayparameter:int sum_array(int n, int a[]); /* Version 3a */int sum_array(int, int []); /* Version 3b */
• Leavingthebracketsemptyisn’tagoodchoice,becauseitdoesn’texposetherelationshipbetweenn anda.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 116
Variable-LengthArrayParameters(C99)• Ingeneral,thelengthofavariable-lengtharrayparametercanbeanyexpression.• Afunctionthatconcatenatestwoarraysa andb,storingtheresultintoathirdarraynamedc:int concatenate(int m, int n, int a[m], int b[n],
int c[m+n]){
…}
• Theexpressionusedtospecifythelengthofc involvestwootherparameters,butingeneralitcouldrefertovariablesoutsidethefunctionorevencallotherfunctions.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 117
Variable-LengthArrayParameters(C99)• Variable-lengtharrayparameterswithasingledimensionhavelimitedusefulness.
• Theymakeafunctiondeclarationordefinitionmoredescriptivebystatingthedesiredlengthofanarrayargument.
• However,noadditionalerror-checkingisperformed;it’sstillpossibleforanarrayargumenttobetoolongortooshort.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 118
Variable-LengthArrayParameters(C99)• Variable-lengtharrayparametersaremostusefulformultidimensionalarrays.
• Byusingavariable-lengtharrayparameter,wecangeneralizethesum_two_dimensional_array functiontoanynumberofcolumns:int sum_two_dimensional_array(int n, int m, int a[n][m]){int i, j, sum = 0;
for (i = 0; i < n; i++)for (j = 0; j < m; j++)sum += a[i][j];
return sum;}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 119
Variable-LengthArrayParameters(C99)• Prototypesforthisfunctioninclude:int sum_two_dimensional_array(int n, int m, int a[n][m]);int sum_two_dimensional_array(int n, int m, int a[*][*]);int sum_two_dimensional_array(int n, int m, int a[][m]);int sum_two_dimensional_array(int n, int m, int a[][*]);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 120
Usingstatic inArrayParameterDeclarations(C99)• C99allowstheuseofthekeywordstatic inthedeclarationofarrayparameters.• Thefollowingexampleusesstatic toindicatethatthelengthofa isguaranteedtobeatleast3:int sum_array(int a[static 3], int n){…
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 121
Usingstatic inArrayParameterDeclarations(C99)
• Usingstatic hasnoeffectonprogrambehavior.
• Thepresenceofstatic ismerelya“hint”thatmayallowaCcompilertogeneratefasterinstructionsforaccessingthearray.• Ifanarrayparameterhasmorethanonedimension,static canbeusedonlyinthefirstdimension.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 122
CompoundLiterals(C99)• Let’sreturntotheoriginalsum_array function.• Whensum_array iscalled,thefirstargumentisusuallythenameofanarray.• Example:int b[] = {3, 0, 3, 4, 1};total = sum_array(b, 5);
• bmustbedeclaredasavariableandtheninitializedpriortothecall.• Ifb isn’tneededforanyotherpurpose,itcanbeannoyingtocreateitsolelyforthepurposeofcallingsum_array.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 123
CompoundLiterals(C99)• InC99,wecanavoidthisannoyancebyusingacompoundliteral:anunnamedarraythat’screated“onthefly”bysimplyspecifyingwhichelementsitcontains.• Acallofsum_array withacompoundliteral(showninbold)asitsfirstargument:total = sum_array((int []){3, 0, 3, 4, 1}, 5);
• Wedidn’tspecifythelengthofthearray,soit’sdeterminedbythenumberofelementsintheliteral.
• Wealsohavetheoptionofspecifyingalengthexplicitly:(int [4]){1, 9, 2, 1}
isequivalentto(int []){1, 9, 2, 1}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 124
CompoundLiterals(C99)• Acompoundliteralresemblesacastappliedtoaninitializer.• Infact,compoundliteralsandinitializersobeythesamerules.• Acompoundliteralmaycontaindesignators,justlikeadesignatedinitializer,anditmayfailtoprovidefullinitialization(inwhichcaseanyuninitializedelementsdefaulttozero).• Forexample,theliteral(int [10]){8, 6} has10elements;thefirsttwohavethevalues8and6,andtheremainingelementshavethevalue0.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 125
CompoundLiterals(C99)• Compoundliteralscreatedinsideafunctionmaycontainarbitraryexpressions,notjustconstants:total = sum_array((int []){2 * i, i + j, j * k}, 3);
• Acompoundliteralisanlvalue,sothevaluesofitselementscanbechanged.
• Ifdesired,acompoundliteralcanbemade“read-only”byaddingthewordconst toitstype:(const int []){5, 4}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 126
Thereturn Statement• Anon-void functionmustusethereturn statementtospecifywhatvalueitwillreturn.• Thereturn statementhastheformreturn expression ;
• Theexpressionisoftenjustaconstantorvariable:return 0;return status;
• Morecomplexexpressionsarepossible:return n >= 0 ? n : 0;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 127
Thereturn Statement• Ifthetypeoftheexpressioninareturn statementdoesn’tmatchthefunction’sreturntype,theexpressionwillbeimplicitlyconvertedtothereturntype.• Ifafunctionreturnsanint,butthereturn statementcontainsadouble expression,thevalueoftheexpressionisconvertedtoint.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 128
Thereturn Statement• return statementsmayappearinfunctionswhosereturntypeisvoid,providedthatnoexpressionisgiven:return; /* return in a void function */
• Example:void print_int(int i){if (i < 0)return;
printf("%d", i);}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 129
Thereturn Statement• Areturn statementmayappearattheendofavoid function:void print_pun(void){printf("To C, or not to C: that is the question.\n");return; /* OK, but not needed */
}
Usingreturn hereisunnecessary.
• Ifanon-void functionfailstoexecuteareturn statement,thebehavioroftheprogramisundefinedifitattemptstousethefunction’sreturnvalue.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 130
ProgramTermination• Normally,thereturntypeofmain isint:int main(void){…
}
• OlderCprogramsoftenomitmain’sreturntype,takingadvantageofthefactthatittraditionallydefaultstoint:main(){…
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 131
ProgramTermination• Omittingthereturntypeofafunctionisn’tlegalinC99,soit’sbesttoavoidthispractice.• Omittingthewordvoid inmain’sparameterlistremainslegal,but—asamatterofstyle—it’sbesttoincludeit.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 132
ProgramTermination• Thevaluereturnedbymain isastatuscodethatcanbetestedwhentheprogramterminates.• main shouldreturn0iftheprogramterminatesnormally.
• Toindicateabnormaltermination,main shouldreturnavalueotherthan0.
• It’sgoodpracticetomakesurethateveryCprogramreturnsastatuscode.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 133
Theexit Function• Executingareturn statementinmain isonewaytoterminateaprogram.• Anotheriscallingtheexit function,whichbelongsto<stdlib.h>.
• Theargumentpassedtoexit hasthesamemeaningasmain’sreturnvalue:bothindicatetheprogram’sstatusattermination.
• Toindicatenormaltermination,we’dpass0:exit(0); /* normal termination */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 134
Theexit Function• Since0isabitcryptic,CallowsustopassEXIT_SUCCESSinstead(theeffectisthesame):exit(EXIT_SUCCESS);
• PassingEXIT_FAILURE indicatesabnormaltermination:exit(EXIT_FAILURE);
• EXIT_SUCCESS andEXIT_FAILURE aremacrosdefinedin<stdlib.h>.• ThevaluesofEXIT_SUCCESS andEXIT_FAILURE areimplementation-defined;typicalvaluesare0and1,respectively.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 135
Theexit Function• Thestatementreturn expression;inmain isequivalenttoexit(expression);• Thedifferencebetweenreturn andexit isthatexit causesprogramterminationregardlessofwhichfunctioncallsit.• Thereturn statementcausesprogramterminationonlywhenitappearsinthemain function.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 136
Recursion• Afunctionisrecursive ifitcallsitself.• Thefollowingfunctioncomputesn!recursively,usingtheformulan!=n × (n – 1)!:int fact(int n){if (n <= 1) return 1;
elsereturn n * fact(n - 1);
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 137
Recursion• Toseehowrecursionworks,let’stracetheexecutionofthestatementi = fact(3);
fact(3) findsthat3isnotlessthanorequalto1,soitcalls
fact(2),whichfindsthat2isnotlessthanorequalto1,soitcalls
fact(1),whichfindsthat1islessthanorequalto1,soitreturns1,causing
fact(2) toreturn2× 1=2,causing
fact(3) toreturn3× 2=6.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 138
Recursion• Thefollowingrecursivefunctioncomputesxn,usingtheformulaxn =x × xn–1.int power(int x, int n){if (n == 0)return 1;
elsereturn x * power(x, n - 1);
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 139
Recursion• Wecancondensethepower functionbyputtingaconditionalexpressioninthereturn statement:int power(int x, int n){return n == 0 ? 1 : x * power(x, n - 1);
}
• Bothfact andpower arecarefultotesta“terminationcondition”assoonasthey’recalled.
• Allrecursivefunctionsneedsomekindofterminationconditioninordertopreventinfiniterecursion.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 140
TheQuicksortAlgorithm• Recursionismosthelpfulforsophisticatedalgorithmsthatrequireafunctiontocallitselftwoormoretimes.
• Recursionoftenarisesasaresultofanalgorithmdesigntechniqueknownasdivide-and-conquer, inwhichalargeproblemisdividedintosmallerpiecesthatarethentackledbythesamealgorithm.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 141
TheQuicksortAlgorithm• Aclassicexampleofdivide-and-conquercanbefoundinthepopularQuicksort algorithm.
• Assumethatthearraytobesortedisindexedfrom1ton.Quicksortalgorithm
1.Chooseanarrayelemente (the“partitioningelement”),thenrearrangethearraysothatelements1,…,i – 1arelessthanorequaltoe,elementi containse,andelementsi +1,…,n aregreaterthanorequaltoe.
2.Sortelements1,…,i – 1byusingQuicksortrecursively.3.Sortelementsi +1,…,n byusingQuicksortrecursively.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 142
TheQuicksortAlgorithm• Step1oftheQuicksortalgorithmisobviouslycritical.
• Therearevariousmethodstopartitionanarray.
• We’lluseatechniquethat’seasytounderstandbutnotparticularlyefficient.
• Thealgorithmreliesontwo“markers”namedlow andhigh,whichkeeptrackofpositionswithinthearray.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 143
TheQuicksortAlgorithm• Initially,low pointstothefirstelement;high pointstothelast.
• Wecopythefirstelement(thepartitioningelement)intoatemporarylocation,leavinga“hole”inthearray.
• Next,wemovehigh acrossthearrayfromrighttoleftuntilitpointstoanelementthat’ssmallerthanthepartitioningelement.
• Wethencopytheelementintotheholethatlow pointsto,whichcreatesanewhole(pointedtobyhigh).
• Wenowmovelow fromlefttoright,lookingforanelementthat’slargerthanthepartitioningelement.Whenwefindone,wecopyitintotheholethathigh pointsto.
• Theprocessrepeatsuntillow andhighmeetatahole.
• Finally,wecopythepartitioningelementintothehole.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 144
TheQuicksortAlgorithm• Exampleofpartitioninganarray:
Copyright©2008W.W.Norton&Company.Allrightsreserved. 145
TheQuicksortAlgorithm• Bythefinalfigure,allelementstotheleftofthepartitioningelementarelessthanorequalto12,andallelementstotherightaregreaterthanorequalto12.• Nowthatthearrayhasbeenpartitioned,wecanuseQuicksortrecursivelytosortthefirstfourelementsofthearray(10,3,6,and7)andthelasttwo(15and18).
Copyright©2008W.W.Norton&Company.Allrightsreserved. 146
Program:Quicksort• Let’sdeveloparecursivefunctionnamedquicksortthatusestheQuicksortalgorithmtosortanarrayofintegers.• Theqsort.c programreads10numbersintoanarray,callsquicksort tosortthearray,thenprintstheelementsinthearray:Enter 10 numbers to be sorted: 9 16 47 82 4 66 12 3 25 51In sorted order: 3 4 9 12 16 25 47 51 66 82
• Thecodeforpartitioningthearrayisinaseparatefunctionnamedsplit.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 147
qsort.c/* Sorts an array of integers using Quicksort algorithm */
#include <stdio.h>
#define N 10
void quicksort(int a[], int low, int high);int split(int a[], int low, int high);
int main(void){int a[N], i;
printf("Enter %d numbers to be sorted: ", N);for (i = 0; i < N; i++)scanf("%d", &a[i]);
quicksort(a, 0, N - 1);
printf("In sorted order: ");for (i = 0; i < N; i++)printf("%d ", a[i]);
printf("\n");return 0;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 148
void quicksort(int a[], int low, int high){int middle;
if (low >= high) return;middle = split(a, low, high);quicksort(a, low, middle - 1);quicksort(a, middle + 1, high);
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 149
int split(int a[], int low, int high){int part_element = a[low];
for (;;) {while (low < high && part_element <= a[high])high--;
if (low >= high) break;a[low++] = a[high];
while (low < high && a[low] <= part_element)low++;
if (low >= high) break;a[high--] = a[low];
}
a[high] = part_element;return high;
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 150
Program:Quicksort• Waystoimprovetheprogram’sperformance:• Improvethepartitioningalgorithm.• Useadifferentmethodtosortsmallarrays.• MakeQuicksort nonrecursive.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 151